diff options
Diffstat (limited to 'libgo')
137 files changed, 1418 insertions, 1308 deletions
diff --git a/libgo/MERGE b/libgo/MERGE index 9847f4715a5..0bcb056063c 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -0beb796b4ef8 +0c39eee85b0d The first line of this file holds the Mercurial revision number of the last merge done from the master library sources. diff --git a/libgo/go/archive/tar/reader.go b/libgo/go/archive/tar/reader.go index 76955e2ec03..13fe2700f9b 100644 --- a/libgo/go/archive/tar/reader.go +++ b/libgo/go/archive/tar/reader.go @@ -80,7 +80,7 @@ func (tr *Reader) octal(b []byte) int64 { for len(b) > 0 && (b[len(b)-1] == ' ' || b[len(b)-1] == '\x00') { b = b[0 : len(b)-1] } - x, err := strconv.Btoui64(cString(b), 8) + x, err := strconv.ParseUint(cString(b), 8, 64) if err != nil { tr.err = err } diff --git a/libgo/go/archive/tar/reader_test.go b/libgo/go/archive/tar/reader_test.go index 5ca4212ae7b..5829d03faa6 100644 --- a/libgo/go/archive/tar/reader_test.go +++ b/libgo/go/archive/tar/reader_test.go @@ -24,7 +24,7 @@ type untarTest struct { var gnuTarTest = &untarTest{ file: "testdata/gnu.tar", headers: []*Header{ - &Header{ + { Name: "small.txt", Mode: 0640, Uid: 73025, @@ -35,7 +35,7 @@ var gnuTarTest = &untarTest{ Uname: "dsymonds", Gname: "eng", }, - &Header{ + { Name: "small2.txt", Mode: 0640, Uid: 73025, @@ -55,10 +55,10 @@ var gnuTarTest = &untarTest{ var untarTests = []*untarTest{ gnuTarTest, - &untarTest{ + { file: "testdata/star.tar", headers: []*Header{ - &Header{ + { Name: "small.txt", Mode: 0640, Uid: 73025, @@ -71,7 +71,7 @@ var untarTests = []*untarTest{ AccessTime: time.Unix(1244592783, 0), ChangeTime: time.Unix(1244592783, 0), }, - &Header{ + { Name: "small2.txt", Mode: 0640, Uid: 73025, @@ -86,10 +86,10 @@ var untarTests = []*untarTest{ }, }, }, - &untarTest{ + { file: "testdata/v7.tar", headers: []*Header{ - &Header{ + { Name: "small.txt", Mode: 0444, Uid: 73025, @@ -98,7 +98,7 @@ var untarTests = []*untarTest{ ModTime: time.Unix(1244593104, 0), Typeflag: '\x00', }, - &Header{ + { Name: "small2.txt", Mode: 0444, Uid: 73025, diff --git a/libgo/go/archive/tar/writer.go b/libgo/go/archive/tar/writer.go index b9310b3f189..d35726bf9d8 100644 --- a/libgo/go/archive/tar/writer.go +++ b/libgo/go/archive/tar/writer.go @@ -79,7 +79,7 @@ func (tw *Writer) cString(b []byte, s string) { // Encode x as an octal ASCII string and write it into b with leading zeros. func (tw *Writer) octal(b []byte, x int64) { - s := strconv.Itob64(x, 8) + s := strconv.FormatInt(x, 8) // leading zeros, but leave room for a NUL. for len(s)+1 < len(b) { s = "0" + s @@ -90,7 +90,7 @@ func (tw *Writer) octal(b []byte, x int64) { // Write x into b, either as octal or as binary (GNUtar/star extension). func (tw *Writer) numeric(b []byte, x int64) { // Try octal first. - s := strconv.Itob64(x, 8) + s := strconv.FormatInt(x, 8) if len(s) < len(b) { tw.octal(b, x) return diff --git a/libgo/go/archive/tar/writer_test.go b/libgo/go/archive/tar/writer_test.go index 8d7ed32d32e..0b413722dd3 100644 --- a/libgo/go/archive/tar/writer_test.go +++ b/libgo/go/archive/tar/writer_test.go @@ -29,10 +29,10 @@ var writerTests = []*writerTest{ // tar (GNU tar) 1.26 // ln -s small.txt link.txt // tar -b 1 --format=ustar -c -f writer.tar small.txt small2.txt link.txt - &writerTest{ + { file: "testdata/writer.tar", entries: []*writerTestEntry{ - &writerTestEntry{ + { header: &Header{ Name: "small.txt", Mode: 0640, @@ -46,7 +46,7 @@ var writerTests = []*writerTest{ }, contents: "Kilts", }, - &writerTestEntry{ + { header: &Header{ Name: "small2.txt", Mode: 0640, @@ -60,7 +60,7 @@ var writerTests = []*writerTest{ }, contents: "Google.com\n", }, - &writerTestEntry{ + { header: &Header{ Name: "link.txt", Mode: 0777, @@ -80,10 +80,10 @@ var writerTests = []*writerTest{ // The truncated test file was produced using these commands: // dd if=/dev/zero bs=1048576 count=16384 > /tmp/16gig.txt // tar -b 1 -c -f- /tmp/16gig.txt | dd bs=512 count=8 > writer-big.tar - &writerTest{ + { file: "testdata/writer-big.tar", entries: []*writerTestEntry{ - &writerTestEntry{ + { header: &Header{ Name: "tmp/16gig.txt", Mode: 0640, diff --git a/libgo/go/archive/zip/writer_test.go b/libgo/go/archive/zip/writer_test.go index 25491dc753d..1188103568e 100644 --- a/libgo/go/archive/zip/writer_test.go +++ b/libgo/go/archive/zip/writer_test.go @@ -21,12 +21,12 @@ type WriteTest struct { } var writeTests = []WriteTest{ - WriteTest{ + { Name: "foo", Data: []byte("Rabbits, guinea pigs, gophers, marsupial rats, and quolls."), Method: Store, }, - WriteTest{ + { Name: "bar", Data: nil, // large data set in the test Method: Deflate, diff --git a/libgo/go/compress/bzip2/bit_reader.go b/libgo/go/compress/bzip2/bit_reader.go index b2c13e50ca4..b35c69a1cca 100644 --- a/libgo/go/compress/bzip2/bit_reader.go +++ b/libgo/go/compress/bzip2/bit_reader.go @@ -20,7 +20,7 @@ type bitReader struct { err error } -// bitReader needs to read bytes from an io.Reader. We attempt to cast the +// bitReader needs to read bytes from an io.Reader. We attempt to convert the // given io.Reader to this interface and, if it doesn't already fit, we wrap in // a bufio.Reader. type byteReader interface { diff --git a/libgo/go/compress/flate/deflate_test.go b/libgo/go/compress/flate/deflate_test.go index db2d71d7350..b4876b0f8b3 100644 --- a/libgo/go/compress/flate/deflate_test.go +++ b/libgo/go/compress/flate/deflate_test.go @@ -30,44 +30,44 @@ type reverseBitsTest struct { } var deflateTests = []*deflateTest{ - &deflateTest{[]byte{}, 0, []byte{1, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11}, -1, []byte{18, 4, 4, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11}, DefaultCompression, []byte{18, 4, 4, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11}, 4, []byte{18, 4, 4, 0, 0, 255, 255}}, - - &deflateTest{[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0, + {[]byte{}, 0, []byte{1, 0, 0, 255, 255}}, + {[]byte{0x11}, -1, []byte{18, 4, 4, 0, 0, 255, 255}}, + {[]byte{0x11}, DefaultCompression, []byte{18, 4, 4, 0, 0, 255, 255}}, + {[]byte{0x11}, 4, []byte{18, 4, 4, 0, 0, 255, 255}}, + + {[]byte{0x11}, 0, []byte{0, 1, 0, 254, 255, 17, 1, 0, 0, 255, 255}}, + {[]byte{0x11, 0x12}, 0, []byte{0, 2, 0, 253, 255, 17, 18, 1, 0, 0, 255, 255}}, + {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 0, []byte{0, 8, 0, 247, 255, 17, 17, 17, 17, 17, 17, 17, 17, 1, 0, 0, 255, 255}, }, - &deflateTest{[]byte{}, 1, []byte{1, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11}, 1, []byte{18, 4, 4, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11, 0x12}, 1, []byte{18, 20, 2, 4, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 1, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}}, - &deflateTest{[]byte{}, 9, []byte{1, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11}, 9, []byte{18, 4, 4, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11, 0x12}, 9, []byte{18, 20, 2, 4, 0, 0, 255, 255}}, - &deflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 9, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}}, + {[]byte{}, 1, []byte{1, 0, 0, 255, 255}}, + {[]byte{0x11}, 1, []byte{18, 4, 4, 0, 0, 255, 255}}, + {[]byte{0x11, 0x12}, 1, []byte{18, 20, 2, 4, 0, 0, 255, 255}}, + {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 1, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}}, + {[]byte{}, 9, []byte{1, 0, 0, 255, 255}}, + {[]byte{0x11}, 9, []byte{18, 4, 4, 0, 0, 255, 255}}, + {[]byte{0x11, 0x12}, 9, []byte{18, 20, 2, 4, 0, 0, 255, 255}}, + {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, 9, []byte{18, 132, 2, 64, 0, 0, 0, 255, 255}}, } var deflateInflateTests = []*deflateInflateTest{ - &deflateInflateTest{[]byte{}}, - &deflateInflateTest{[]byte{0x11}}, - &deflateInflateTest{[]byte{0x11, 0x12}}, - &deflateInflateTest{[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}}, - &deflateInflateTest{[]byte{0x11, 0x10, 0x13, 0x41, 0x21, 0x21, 0x41, 0x13, 0x87, 0x78, 0x13}}, - &deflateInflateTest{largeDataChunk()}, + {[]byte{}}, + {[]byte{0x11}}, + {[]byte{0x11, 0x12}}, + {[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}}, + {[]byte{0x11, 0x10, 0x13, 0x41, 0x21, 0x21, 0x41, 0x13, 0x87, 0x78, 0x13}}, + {largeDataChunk()}, } var reverseBitsTests = []*reverseBitsTest{ - &reverseBitsTest{1, 1, 1}, - &reverseBitsTest{1, 2, 2}, - &reverseBitsTest{1, 3, 4}, - &reverseBitsTest{1, 4, 8}, - &reverseBitsTest{1, 5, 16}, - &reverseBitsTest{17, 5, 17}, - &reverseBitsTest{257, 9, 257}, - &reverseBitsTest{29, 5, 23}, + {1, 1, 1}, + {1, 2, 2}, + {1, 3, 4}, + {1, 4, 8}, + {1, 5, 16}, + {17, 5, 17}, + {257, 9, 257}, + {29, 5, 23}, } func largeDataChunk() []byte { diff --git a/libgo/go/compress/flate/flate_test.go b/libgo/go/compress/flate/flate_test.go index bfd3b8381d0..94efc90acfa 100644 --- a/libgo/go/compress/flate/flate_test.go +++ b/libgo/go/compress/flate/flate_test.go @@ -52,7 +52,7 @@ type InitDecoderTest struct { var initDecoderTests = []*InitDecoderTest{ // Example from Connell 1973, - &InitDecoderTest{ + { []int{3, 5, 2, 4, 3, 5, 5, 4, 4, 3, 4, 5}, huffmanDecoder{ 2, 5, @@ -68,7 +68,7 @@ var initDecoderTests = []*InitDecoderTest{ }, // Example from RFC 1951 section 3.2.2 - &InitDecoderTest{ + { []int{2, 1, 3, 3}, huffmanDecoder{ 1, 3, @@ -80,7 +80,7 @@ var initDecoderTests = []*InitDecoderTest{ }, // Second example from RFC 1951 section 3.2.2 - &InitDecoderTest{ + { []int{3, 3, 3, 3, 3, 2, 4, 4}, huffmanDecoder{ 2, 4, @@ -92,21 +92,21 @@ var initDecoderTests = []*InitDecoderTest{ }, // Static Huffman codes (RFC 1951 section 3.2.6) - &InitDecoderTest{ + { fixedHuffmanBits[0:], fixedHuffmanDecoder, true, }, // Illegal input. - &InitDecoderTest{ + { []int{}, huffmanDecoder{}, false, }, // Illegal input. - &InitDecoderTest{ + { []int{0, 0, 0, 0, 0, 0, 0}, huffmanDecoder{}, false, diff --git a/libgo/go/compress/flate/huffman_bit_writer.go b/libgo/go/compress/flate/huffman_bit_writer.go index efd99c6b954..8d0b4f9c1e8 100644 --- a/libgo/go/compress/flate/huffman_bit_writer.go +++ b/libgo/go/compress/flate/huffman_bit_writer.go @@ -106,8 +106,8 @@ func newHuffmanBitWriter(w io.Writer) *huffmanBitWriter { } func (err WrongValueError) Error() string { - return "huffmanBitWriter: " + err.name + " should belong to [" + strconv.Itoa64(int64(err.from)) + ";" + - strconv.Itoa64(int64(err.to)) + "] but actual value is " + strconv.Itoa64(int64(err.value)) + return "huffmanBitWriter: " + err.name + " should belong to [" + strconv.FormatInt(int64(err.from), 10) + ";" + + strconv.FormatInt(int64(err.to), 10) + "] but actual value is " + strconv.FormatInt(int64(err.value), 10) } func (w *huffmanBitWriter) flushBits() { diff --git a/libgo/go/compress/flate/inflate.go b/libgo/go/compress/flate/inflate.go index 3f0c94864a4..3f2042bfe92 100644 --- a/libgo/go/compress/flate/inflate.go +++ b/libgo/go/compress/flate/inflate.go @@ -25,7 +25,7 @@ const ( type CorruptInputError int64 func (e CorruptInputError) Error() string { - return "flate: corrupt input before offset " + strconv.Itoa64(int64(e)) + return "flate: corrupt input before offset " + strconv.FormatInt(int64(e), 10) } // An InternalError reports an error in the flate code itself. @@ -40,7 +40,7 @@ type ReadError struct { } func (e *ReadError) Error() string { - return "flate: read error at offset " + strconv.Itoa64(e.Offset) + ": " + e.Err.Error() + return "flate: read error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error() } // A WriteError reports an error encountered while writing output. @@ -50,7 +50,7 @@ type WriteError struct { } func (e *WriteError) Error() string { - return "flate: write error at offset " + strconv.Itoa64(e.Offset) + ": " + e.Err.Error() + return "flate: write error at offset " + strconv.FormatInt(e.Offset, 10) + ": " + e.Err.Error() } // Huffman decoder is based on diff --git a/libgo/go/crypto/aes/aes_test.go b/libgo/go/crypto/aes/aes_test.go index 2136d447d01..3505d33e960 100644 --- a/libgo/go/crypto/aes/aes_test.go +++ b/libgo/go/crypto/aes/aes_test.go @@ -348,3 +348,17 @@ func TestCipherDecrypt(t *testing.T) { } } } + +func BenchmarkEncrypt(b *testing.B) { + b.StopTimer() + tt := encryptTests[0] + c, err := NewCipher(tt.key) + if err != nil { + panic("NewCipher") + } + out := make([]byte, len(tt.in)) + b.StartTimer() + for i := 0; i < b.N; i++ { + c.Encrypt(out, tt.in) + } +} diff --git a/libgo/go/crypto/aes/block.go b/libgo/go/crypto/aes/block.go index 130cd011c94..37b0dd05841 100644 --- a/libgo/go/crypto/aes/block.go +++ b/libgo/go/crypto/aes/block.go @@ -56,10 +56,10 @@ func encryptBlock(xk []uint32, dst, src []byte) { nr := len(xk)/4 - 2 // - 2: one above, one more below k := 4 for r := 0; r < nr; r++ { - t0 = xk[k+0] ^ te[0][s0>>24] ^ te[1][s1>>16&0xff] ^ te[2][s2>>8&0xff] ^ te[3][s3&0xff] - t1 = xk[k+1] ^ te[0][s1>>24] ^ te[1][s2>>16&0xff] ^ te[2][s3>>8&0xff] ^ te[3][s0&0xff] - t2 = xk[k+2] ^ te[0][s2>>24] ^ te[1][s3>>16&0xff] ^ te[2][s0>>8&0xff] ^ te[3][s1&0xff] - t3 = xk[k+3] ^ te[0][s3>>24] ^ te[1][s0>>16&0xff] ^ te[2][s1>>8&0xff] ^ te[3][s2&0xff] + t0 = xk[k+0] ^ te[0][uint8(s0>>24)] ^ te[1][uint8(s1>>16)] ^ te[2][uint8(s2>>8)] ^ te[3][uint8(s3)] + t1 = xk[k+1] ^ te[0][uint8(s1>>24)] ^ te[1][uint8(s2>>16)] ^ te[2][uint8(s3>>8)] ^ te[3][uint8(s0)] + t2 = xk[k+2] ^ te[0][uint8(s2>>24)] ^ te[1][uint8(s3>>16)] ^ te[2][uint8(s0>>8)] ^ te[3][uint8(s1)] + t3 = xk[k+3] ^ te[0][uint8(s3>>24)] ^ te[1][uint8(s0>>16)] ^ te[2][uint8(s1>>8)] ^ te[3][uint8(s2)] k += 4 s0, s1, s2, s3 = t0, t1, t2, t3 } @@ -101,10 +101,10 @@ func decryptBlock(xk []uint32, dst, src []byte) { nr := len(xk)/4 - 2 // - 2: one above, one more below k := 4 for r := 0; r < nr; r++ { - t0 = xk[k+0] ^ td[0][s0>>24] ^ td[1][s3>>16&0xff] ^ td[2][s2>>8&0xff] ^ td[3][s1&0xff] - t1 = xk[k+1] ^ td[0][s1>>24] ^ td[1][s0>>16&0xff] ^ td[2][s3>>8&0xff] ^ td[3][s2&0xff] - t2 = xk[k+2] ^ td[0][s2>>24] ^ td[1][s1>>16&0xff] ^ td[2][s0>>8&0xff] ^ td[3][s3&0xff] - t3 = xk[k+3] ^ td[0][s3>>24] ^ td[1][s2>>16&0xff] ^ td[2][s1>>8&0xff] ^ td[3][s0&0xff] + t0 = xk[k+0] ^ td[0][uint8(s0>>24)] ^ td[1][uint8(s3>>16)] ^ td[2][uint8(s2>>8)] ^ td[3][uint8(s1)] + t1 = xk[k+1] ^ td[0][uint8(s1>>24)] ^ td[1][uint8(s0>>16)] ^ td[2][uint8(s3>>8)] ^ td[3][uint8(s2)] + t2 = xk[k+2] ^ td[0][uint8(s2>>24)] ^ td[1][uint8(s1>>16)] ^ td[2][uint8(s0>>8)] ^ td[3][uint8(s3)] + t3 = xk[k+3] ^ td[0][uint8(s3>>24)] ^ td[1][uint8(s2>>16)] ^ td[2][uint8(s1>>8)] ^ td[3][uint8(s0)] k += 4 s0, s1, s2, s3 = t0, t1, t2, t3 } diff --git a/libgo/go/crypto/hmac/hmac.go b/libgo/go/crypto/hmac/hmac.go index deaceafb260..6e7dd8762c8 100644 --- a/libgo/go/crypto/hmac/hmac.go +++ b/libgo/go/crypto/hmac/hmac.go @@ -49,14 +49,13 @@ func (h *hmac) tmpPad(xor byte) { } func (h *hmac) Sum(in []byte) []byte { - sum := h.inner.Sum(nil) + origLen := len(in) + in = h.inner.Sum(in) h.tmpPad(0x5c) - for i, b := range sum { - h.tmp[padSize+i] = b - } + copy(h.tmp[padSize:], in[origLen:]) h.outer.Reset() h.outer.Write(h.tmp) - return h.outer.Sum(in) + return h.outer.Sum(in[:origLen]) } func (h *hmac) Write(p []byte) (n int, err error) { diff --git a/libgo/go/crypto/md5/md5.go b/libgo/go/crypto/md5/md5.go index 182cfb85370..f4e7b09ebf2 100644 --- a/libgo/go/crypto/md5/md5.go +++ b/libgo/go/crypto/md5/md5.go @@ -79,8 +79,7 @@ func (d *digest) Write(p []byte) (nn int, err error) { func (d0 *digest) Sum(in []byte) []byte { // Make a copy of d0 so that caller can keep writing and summing. - d := new(digest) - *d = *d0 + d := *d0 // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. len := d.len @@ -103,11 +102,13 @@ func (d0 *digest) Sum(in []byte) []byte { panic("d.nx != 0") } - for _, s := range d.s { - in = append(in, byte(s>>0)) - in = append(in, byte(s>>8)) - in = append(in, byte(s>>16)) - in = append(in, byte(s>>24)) + var digest [Size]byte + for i, s := range d.s { + digest[i*4] = byte(s) + digest[i*4+1] = byte(s >> 8) + digest[i*4+2] = byte(s >> 16) + digest[i*4+3] = byte(s >> 24) } - return in + + return append(in, digest[:]...) } diff --git a/libgo/go/crypto/openpgp/s2k/s2k.go b/libgo/go/crypto/openpgp/s2k/s2k.go index 83673e17335..8bc0bb320bb 100644 --- a/libgo/go/crypto/openpgp/s2k/s2k.go +++ b/libgo/go/crypto/openpgp/s2k/s2k.go @@ -26,6 +26,7 @@ var zero [1]byte // 4880, section 3.7.1.2) using the given hash, input passphrase and salt. func Salted(out []byte, h hash.Hash, in []byte, salt []byte) { done := 0 + var digest []byte for i := 0; done < len(out); i++ { h.Reset() @@ -34,7 +35,8 @@ func Salted(out []byte, h hash.Hash, in []byte, salt []byte) { } h.Write(salt) h.Write(in) - n := copy(out[done:], h.Sum(nil)) + digest = h.Sum(digest[:0]) + n := copy(out[done:], digest) done += n } } @@ -52,6 +54,7 @@ func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) { } done := 0 + var digest []byte for i := 0; done < len(out); i++ { h.Reset() for j := 0; j < i; j++ { @@ -68,7 +71,8 @@ func Iterated(out []byte, h hash.Hash, in []byte, salt []byte, count int) { written += len(combined) } } - n := copy(out[done:], h.Sum(nil)) + digest = h.Sum(digest[:0]) + n := copy(out[done:], digest) done += n } } diff --git a/libgo/go/crypto/openpgp/write.go b/libgo/go/crypto/openpgp/write.go index 60dae01e64b..bdee57d767c 100644 --- a/libgo/go/crypto/openpgp/write.go +++ b/libgo/go/crypto/openpgp/write.go @@ -183,7 +183,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint for i := range to { encryptKeys[i] = to[i].encryptionKey() if encryptKeys[i].PublicKey == nil { - return nil, error_.InvalidArgumentError("cannot encrypt a message to key id " + strconv.Uitob64(to[i].PrimaryKey.KeyId, 16) + " because it has no encryption keys") + return nil, error_.InvalidArgumentError("cannot encrypt a message to key id " + strconv.FormatUint(to[i].PrimaryKey.KeyId, 16) + " because it has no encryption keys") } sig := to[i].primaryIdentity().SelfSignature diff --git a/libgo/go/crypto/ripemd160/ripemd160.go b/libgo/go/crypto/ripemd160/ripemd160.go index c128ee445a5..cd2cc39dbd1 100644 --- a/libgo/go/crypto/ripemd160/ripemd160.go +++ b/libgo/go/crypto/ripemd160/ripemd160.go @@ -83,8 +83,7 @@ func (d *digest) Write(p []byte) (nn int, err error) { func (d0 *digest) Sum(in []byte) []byte { // Make a copy of d0 so that caller can keep writing and summing. - d := new(digest) - *d = *d0 + d := *d0 // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. tc := d.tc @@ -107,11 +106,13 @@ func (d0 *digest) Sum(in []byte) []byte { panic("d.nx != 0") } - for _, s := range d.s { - in = append(in, byte(s)) - in = append(in, byte(s>>8)) - in = append(in, byte(s>>16)) - in = append(in, byte(s>>24)) + var digest [Size]byte + for i, s := range d.s { + digest[i*4] = byte(s) + digest[i*4+1] = byte(s >> 8) + digest[i*4+2] = byte(s >> 16) + digest[i*4+3] = byte(s >> 24) } - return in + + return append(in, digest[:]...) } diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go index f74525c103a..c07e8f90db7 100644 --- a/libgo/go/crypto/rsa/rsa.go +++ b/libgo/go/crypto/rsa/rsa.go @@ -189,12 +189,13 @@ func incCounter(c *[4]byte) { // specified in PKCS#1 v2.1. func mgf1XOR(out []byte, hash hash.Hash, seed []byte) { var counter [4]byte + var digest []byte done := 0 for done < len(out) { hash.Write(seed) hash.Write(counter[0:4]) - digest := hash.Sum(nil) + digest = hash.Sum(digest[:0]) hash.Reset() for i := 0; i < len(digest) && done < len(out); i++ { diff --git a/libgo/go/crypto/sha1/sha1.go b/libgo/go/crypto/sha1/sha1.go index f41cdb5b027..7bb68bbdbc8 100644 --- a/libgo/go/crypto/sha1/sha1.go +++ b/libgo/go/crypto/sha1/sha1.go @@ -81,8 +81,7 @@ func (d *digest) Write(p []byte) (nn int, err error) { func (d0 *digest) Sum(in []byte) []byte { // Make a copy of d0 so that caller can keep writing and summing. - d := new(digest) - *d = *d0 + d := *d0 // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. len := d.len @@ -105,11 +104,13 @@ func (d0 *digest) Sum(in []byte) []byte { panic("d.nx != 0") } - for _, s := range d.h { - in = append(in, byte(s>>24)) - in = append(in, byte(s>>16)) - in = append(in, byte(s>>8)) - in = append(in, byte(s)) + var digest [Size]byte + for i, s := range d.h { + digest[i*4] = byte(s >> 24) + digest[i*4+1] = byte(s >> 16) + digest[i*4+2] = byte(s >> 8) + digest[i*4+3] = byte(s) } - return in + + return append(in, digest[:]...) } diff --git a/libgo/go/crypto/sha256/sha256.go b/libgo/go/crypto/sha256/sha256.go index 34861f6cf49..4525541a79c 100644 --- a/libgo/go/crypto/sha256/sha256.go +++ b/libgo/go/crypto/sha256/sha256.go @@ -125,8 +125,7 @@ func (d *digest) Write(p []byte) (nn int, err error) { func (d0 *digest) Sum(in []byte) []byte { // Make a copy of d0 so that caller can keep writing and summing. - d := new(digest) - *d = *d0 + d := *d0 // Padding. Add a 1 bit and 0 bits until 56 bytes mod 64. len := d.len @@ -150,14 +149,19 @@ func (d0 *digest) Sum(in []byte) []byte { } h := d.h[:] + size := Size if d.is224 { h = d.h[:7] + size = Size224 } - for _, s := range h { - in = append(in, byte(s>>24)) - in = append(in, byte(s>>16)) - in = append(in, byte(s>>8)) - in = append(in, byte(s)) + + var digest [Size]byte + for i, s := range h { + digest[i*4] = byte(s >> 24) + digest[i*4+1] = byte(s >> 16) + digest[i*4+2] = byte(s >> 8) + digest[i*4+3] = byte(s) } - return in + + return append(in, digest[:size]...) } diff --git a/libgo/go/crypto/sha512/sha512.go b/libgo/go/crypto/sha512/sha512.go index 3cf65cbe7c8..927f28a28d8 100644 --- a/libgo/go/crypto/sha512/sha512.go +++ b/libgo/go/crypto/sha512/sha512.go @@ -150,18 +150,23 @@ func (d0 *digest) Sum(in []byte) []byte { } h := d.h[:] + size := Size if d.is384 { h = d.h[:6] + size = Size384 } - for _, s := range h { - in = append(in, byte(s>>56)) - in = append(in, byte(s>>48)) - in = append(in, byte(s>>40)) - in = append(in, byte(s>>32)) - in = append(in, byte(s>>24)) - in = append(in, byte(s>>16)) - in = append(in, byte(s>>8)) - in = append(in, byte(s)) + + var digest [Size]byte + for i, s := range h { + digest[i*8] = byte(s >> 56) + digest[i*8+1] = byte(s >> 48) + digest[i*8+2] = byte(s >> 40) + digest[i*8+3] = byte(s >> 32) + digest[i*8+4] = byte(s >> 24) + digest[i*8+5] = byte(s >> 16) + digest[i*8+6] = byte(s >> 8) + digest[i*8+7] = byte(s) } - return in + + return append(in, digest[:size]...) } diff --git a/libgo/go/crypto/tls/cipher_suites.go b/libgo/go/crypto/tls/cipher_suites.go index c0e8656f79b..914491d6b4a 100644 --- a/libgo/go/crypto/tls/cipher_suites.go +++ b/libgo/go/crypto/tls/cipher_suites.go @@ -52,12 +52,12 @@ type cipherSuite struct { } var cipherSuites = []*cipherSuite{ - &cipherSuite{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1}, - &cipherSuite{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1}, - &cipherSuite{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1}, - &cipherSuite{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1}, - &cipherSuite{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1}, - &cipherSuite{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1}, + {TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1}, + {TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1}, + {TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1}, + {TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1}, + {TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1}, + {TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1}, } func cipherRC4(key, iv []byte, isRead bool) interface{} { @@ -96,7 +96,7 @@ func macSHA1(version uint16, key []byte) macFunction { type macFunction interface { Size() int - MAC(seq, data []byte) []byte + MAC(digestBuf, seq, data []byte) []byte } // ssl30MAC implements the SSLv3 MAC function, as defined in @@ -114,7 +114,7 @@ var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0 var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c} -func (s ssl30MAC) MAC(seq, record []byte) []byte { +func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte { padLength := 48 if s.h.Size() == 20 { padLength = 40 @@ -127,13 +127,13 @@ func (s ssl30MAC) MAC(seq, record []byte) []byte { s.h.Write(record[:1]) s.h.Write(record[3:5]) s.h.Write(record[recordHeaderLen:]) - digest := s.h.Sum(nil) + digestBuf = s.h.Sum(digestBuf[:0]) s.h.Reset() s.h.Write(s.key) s.h.Write(ssl30Pad2[:padLength]) - s.h.Write(digest) - return s.h.Sum(nil) + s.h.Write(digestBuf) + return s.h.Sum(digestBuf[:0]) } // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3. @@ -145,11 +145,11 @@ func (s tls10MAC) Size() int { return s.h.Size() } -func (s tls10MAC) MAC(seq, record []byte) []byte { +func (s tls10MAC) MAC(digestBuf, seq, record []byte) []byte { s.h.Reset() s.h.Write(seq) s.h.Write(record) - return s.h.Sum(nil) + return s.h.Sum(digestBuf[:0]) } func rsaKA() keyAgreement { diff --git a/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go index b8fa2737f67..6a03fa8042a 100644 --- a/libgo/go/crypto/tls/conn.go +++ b/libgo/go/crypto/tls/conn.go @@ -118,6 +118,9 @@ type halfConn struct { nextCipher interface{} // next encryption state nextMac macFunction // next MAC algorithm + + // used to save allocating a new buffer for each MAC. + inDigestBuf, outDigestBuf []byte } // prepareCipherSpec sets the encryption and MAC states @@ -280,12 +283,13 @@ func (hc *halfConn) decrypt(b *block) (bool, alert) { b.data[4] = byte(n) b.resize(recordHeaderLen + n) remoteMAC := payload[n:] - localMAC := hc.mac.MAC(hc.seq[0:], b.data) + localMAC := hc.mac.MAC(hc.inDigestBuf, hc.seq[0:], b.data) hc.incSeq() if subtle.ConstantTimeCompare(localMAC, remoteMAC) != 1 || paddingGood != 255 { return false, alertBadRecordMAC } + hc.inDigestBuf = localMAC } return true, 0 @@ -312,12 +316,13 @@ func padToBlockSize(payload []byte, blockSize int) (prefix, finalBlock []byte) { func (hc *halfConn) encrypt(b *block) (bool, alert) { // mac if hc.mac != nil { - mac := hc.mac.MAC(hc.seq[0:], b.data) + mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data) hc.incSeq() n := len(b.data) b.resize(n + len(mac)) copy(b.data[n:], mac) + hc.outDigestBuf = mac } payload := b.data[recordHeaderLen:] diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go index b4337f2aac6..e39e59cd5a1 100644 --- a/libgo/go/crypto/tls/handshake_client.go +++ b/libgo/go/crypto/tls/handshake_client.go @@ -231,10 +231,10 @@ func (c *Conn) clientHandshake() error { if cert != nil { certVerify := new(certificateVerifyMsg) - var digest [36]byte - copy(digest[0:16], finishedHash.serverMD5.Sum(nil)) - copy(digest[16:36], finishedHash.serverSHA1.Sum(nil)) - signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey, crypto.MD5SHA1, digest[0:]) + digest := make([]byte, 0, 36) + digest = finishedHash.serverMD5.Sum(digest) + digest = finishedHash.serverSHA1.Sum(digest) + signed, err := rsa.SignPKCS1v15(c.config.rand(), c.config.Certificates[0].PrivateKey, crypto.MD5SHA1, digest) if err != nil { return c.sendAlert(alertInternalError) } diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go index bbb23c0c9f6..89c000dd6e9 100644 --- a/libgo/go/crypto/tls/handshake_server.go +++ b/libgo/go/crypto/tls/handshake_server.go @@ -234,9 +234,9 @@ FindCipherSuite: return c.sendAlert(alertUnexpectedMessage) } - digest := make([]byte, 36) - copy(digest[0:16], finishedHash.serverMD5.Sum(nil)) - copy(digest[16:36], finishedHash.serverSHA1.Sum(nil)) + digest := make([]byte, 0, 36) + digest = finishedHash.serverMD5.Sum(digest) + digest = finishedHash.serverSHA1.Sum(digest) err = rsa.VerifyPKCS1v15(pub, crypto.MD5SHA1, digest, certVerify.signature) if err != nil { c.sendAlert(alertBadCertificate) diff --git a/libgo/go/crypto/tls/handshake_server_test.go b/libgo/go/crypto/tls/handshake_server_test.go index e00c32c5508..d98e13decf6 100644 --- a/libgo/go/crypto/tls/handshake_server_test.go +++ b/libgo/go/crypto/tls/handshake_server_test.go @@ -159,7 +159,7 @@ func TestHandshakeServerSSLv3(t *testing.T) { var serve = flag.Bool("serve", false, "run a TLS server on :10443") var testCipherSuites = flag.String("ciphersuites", - "0x"+strconv.Itob(int(TLS_RSA_WITH_RC4_128_SHA), 16), + "0x"+strconv.FormatInt(int64(TLS_RSA_WITH_RC4_128_SHA), 16), "cipher suites to accept in serving mode") func TestRunServer(t *testing.T) { @@ -170,7 +170,7 @@ func TestRunServer(t *testing.T) { suites := strings.Split(*testCipherSuites, ",") testConfig.CipherSuites = make([]uint16, len(suites)) for i := range suites { - suite, err := strconv.Btoui64(suites[i], 0) + suite, err := strconv.ParseUint(suites[i], 0, 64) if err != nil { panic(err) } diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go index 7e6b5c96f53..65ca3158003 100644 --- a/libgo/go/crypto/x509/x509.go +++ b/libgo/go/crypto/x509/x509.go @@ -927,10 +927,15 @@ func CreateCertificate(rand io.Reader, template, parent *Certificate, pub *rsa.P return } - asn1Issuer, err := asn1.Marshal(parent.Subject.ToRDNSequence()) - if err != nil { - return + var asn1Issuer []byte + if len(parent.RawSubject) > 0 { + asn1Issuer = parent.RawSubject + } else { + if asn1Issuer, err = asn1.Marshal(parent.Subject.ToRDNSequence()); err != nil { + return + } } + asn1Subject, err := asn1.Marshal(template.Subject.ToRDNSequence()) if err != nil { return diff --git a/libgo/go/debug/dwarf/buf.go b/libgo/go/debug/dwarf/buf.go index 6b4af7d53dc..6dc28d2568c 100644 --- a/libgo/go/debug/dwarf/buf.go +++ b/libgo/go/debug/dwarf/buf.go @@ -149,5 +149,5 @@ type DecodeError struct { } func (e DecodeError) Error() string { - return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.Itob64(int64(e.Offset), 16) + ": " + e.Err + return "decoding dwarf section " + e.Name + " at offset 0x" + strconv.FormatInt(int64(e.Offset), 16) + ": " + e.Err } diff --git a/libgo/go/debug/dwarf/const.go b/libgo/go/debug/dwarf/const.go index 1a3fec155c2..918b153d078 100644 --- a/libgo/go/debug/dwarf/const.go +++ b/libgo/go/debug/dwarf/const.go @@ -178,7 +178,7 @@ func (a Attr) GoString() string { return "dwarf.Attr" + s } } - return "dwarf.Attr(" + strconv.Itoa64(int64(a)) + ")" + return "dwarf.Attr(" + strconv.FormatInt(int64(a), 10) + ")" } // A format is a DWARF data encoding format. @@ -347,7 +347,7 @@ func (t Tag) GoString() string { return "dwarf.Tag" + s } } - return "dwarf.Tag(" + strconv.Itoa64(int64(t)) + ")" + return "dwarf.Tag(" + strconv.FormatInt(int64(t), 10) + ")" } // Location expression operators. diff --git a/libgo/go/debug/dwarf/type.go b/libgo/go/debug/dwarf/type.go index e8ce8d57b8c..9be66658fe9 100644 --- a/libgo/go/debug/dwarf/type.go +++ b/libgo/go/debug/dwarf/type.go @@ -110,7 +110,7 @@ type ArrayType struct { } func (t *ArrayType) String() string { - return "[" + strconv.Itoa64(t.Count) + "]" + t.Type.String() + return "[" + strconv.FormatInt(t.Count, 10) + "]" + t.Type.String() } func (t *ArrayType) Size() int64 { return t.Count * t.Type.Size() } @@ -171,10 +171,10 @@ func (t *StructType) Defn() string { s += "; " } s += f.Name + " " + f.Type.String() - s += "@" + strconv.Itoa64(f.ByteOffset) + s += "@" + strconv.FormatInt(f.ByteOffset, 10) if f.BitSize > 0 { - s += " : " + strconv.Itoa64(f.BitSize) - s += "@" + strconv.Itoa64(f.BitOffset) + s += " : " + strconv.FormatInt(f.BitSize, 10) + s += "@" + strconv.FormatInt(f.BitOffset, 10) } } s += "}" @@ -206,7 +206,7 @@ func (t *EnumType) String() string { if i > 0 { s += "; " } - s += v.Name + "=" + strconv.Itoa64(v.Val) + s += v.Name + "=" + strconv.FormatInt(v.Val, 10) } s += "}" return s diff --git a/libgo/go/debug/elf/elf.go b/libgo/go/debug/elf/elf.go index c71b230bd95..03e42b03465 100644 --- a/libgo/go/debug/elf/elf.go +++ b/libgo/go/debug/elf/elf.go @@ -1490,11 +1490,11 @@ func stringName(i uint32, names []intName, goSyntax bool) string { if goSyntax { s = "elf." + s } - return s + "+" + strconv.Uitoa64(uint64(i-n.i)) + return s + "+" + strconv.FormatUint(uint64(i-n.i), 10) } } - return strconv.Uitoa64(uint64(i)) + return strconv.FormatUint(uint64(i), 10) } func flagName(i uint32, names []intName, goSyntax bool) string { @@ -1512,10 +1512,10 @@ func flagName(i uint32, names []intName, goSyntax bool) string { } } if len(s) == 0 { - return "0x" + strconv.Uitob64(uint64(i), 16) + return "0x" + strconv.FormatUint(uint64(i), 16) } if i != 0 { - s += "+0x" + strconv.Uitob64(uint64(i), 16) + s += "+0x" + strconv.FormatUint(uint64(i), 16) } return s } diff --git a/libgo/go/debug/macho/file_test.go b/libgo/go/debug/macho/file_test.go index 56d8a20be2c..640225b3291 100644 --- a/libgo/go/debug/macho/file_test.go +++ b/libgo/go/debug/macho/file_test.go @@ -21,11 +21,11 @@ var fileTests = []fileTest{ "testdata/gcc-386-darwin-exec", FileHeader{0xfeedface, Cpu386, 0x3, 0x2, 0xc, 0x3c0, 0x85}, []*SegmentHeader{ - &SegmentHeader{LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - &SegmentHeader{LoadCmdSegment, 0xc0, "__TEXT", 0x1000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x2, 0x0}, - &SegmentHeader{LoadCmdSegment, 0xc0, "__DATA", 0x2000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x2, 0x0}, - &SegmentHeader{LoadCmdSegment, 0x7c, "__IMPORT", 0x3000, 0x1000, 0x2000, 0x1000, 0x7, 0x7, 0x1, 0x0}, - &SegmentHeader{LoadCmdSegment, 0x38, "__LINKEDIT", 0x4000, 0x1000, 0x3000, 0x12c, 0x7, 0x1, 0x0, 0x0}, + {LoadCmdSegment, 0x38, "__PAGEZERO", 0x0, 0x1000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + {LoadCmdSegment, 0xc0, "__TEXT", 0x1000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x2, 0x0}, + {LoadCmdSegment, 0xc0, "__DATA", 0x2000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x2, 0x0}, + {LoadCmdSegment, 0x7c, "__IMPORT", 0x3000, 0x1000, 0x2000, 0x1000, 0x7, 0x7, 0x1, 0x0}, + {LoadCmdSegment, 0x38, "__LINKEDIT", 0x4000, 0x1000, 0x3000, 0x12c, 0x7, 0x1, 0x0, 0x0}, nil, nil, nil, @@ -35,21 +35,21 @@ var fileTests = []fileTest{ nil, }, []*SectionHeader{ - &SectionHeader{"__text", "__TEXT", 0x1f68, 0x88, 0xf68, 0x2, 0x0, 0x0, 0x80000400}, - &SectionHeader{"__cstring", "__TEXT", 0x1ff0, 0xd, 0xff0, 0x0, 0x0, 0x0, 0x2}, - &SectionHeader{"__data", "__DATA", 0x2000, 0x14, 0x1000, 0x2, 0x0, 0x0, 0x0}, - &SectionHeader{"__dyld", "__DATA", 0x2014, 0x1c, 0x1014, 0x2, 0x0, 0x0, 0x0}, - &SectionHeader{"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008}, + {"__text", "__TEXT", 0x1f68, 0x88, 0xf68, 0x2, 0x0, 0x0, 0x80000400}, + {"__cstring", "__TEXT", 0x1ff0, 0xd, 0xff0, 0x0, 0x0, 0x0, 0x2}, + {"__data", "__DATA", 0x2000, 0x14, 0x1000, 0x2, 0x0, 0x0, 0x0}, + {"__dyld", "__DATA", 0x2014, 0x1c, 0x1014, 0x2, 0x0, 0x0, 0x0}, + {"__jump_table", "__IMPORT", 0x3000, 0xa, 0x2000, 0x6, 0x0, 0x0, 0x4000008}, }, }, { "testdata/gcc-amd64-darwin-exec", FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0x2, 0xb, 0x568, 0x85}, []*SegmentHeader{ - &SegmentHeader{LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x5, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x3, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x48, "__LINKEDIT", 0x100002000, 0x1000, 0x2000, 0x140, 0x7, 0x1, 0x0, 0x0}, + {LoadCmdSegment64, 0x48, "__PAGEZERO", 0x0, 0x100000000, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, + {LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x1000, 0x7, 0x5, 0x5, 0x0}, + {LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x1000, 0x1000, 0x7, 0x3, 0x3, 0x0}, + {LoadCmdSegment64, 0x48, "__LINKEDIT", 0x100002000, 0x1000, 0x2000, 0x140, 0x7, 0x1, 0x0, 0x0}, nil, nil, nil, @@ -59,14 +59,14 @@ var fileTests = []fileTest{ nil, }, []*SectionHeader{ - &SectionHeader{"__text", "__TEXT", 0x100000f14, 0x6d, 0xf14, 0x2, 0x0, 0x0, 0x80000400}, - &SectionHeader{"__symbol_stub1", "__TEXT", 0x100000f81, 0xc, 0xf81, 0x0, 0x0, 0x0, 0x80000408}, - &SectionHeader{"__stub_helper", "__TEXT", 0x100000f90, 0x18, 0xf90, 0x2, 0x0, 0x0, 0x0}, - &SectionHeader{"__cstring", "__TEXT", 0x100000fa8, 0xd, 0xfa8, 0x0, 0x0, 0x0, 0x2}, - &SectionHeader{"__eh_frame", "__TEXT", 0x100000fb8, 0x48, 0xfb8, 0x3, 0x0, 0x0, 0x6000000b}, - &SectionHeader{"__data", "__DATA", 0x100001000, 0x1c, 0x1000, 0x3, 0x0, 0x0, 0x0}, - &SectionHeader{"__dyld", "__DATA", 0x100001020, 0x38, 0x1020, 0x3, 0x0, 0x0, 0x0}, - &SectionHeader{"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7}, + {"__text", "__TEXT", 0x100000f14, 0x6d, 0xf14, 0x2, 0x0, 0x0, 0x80000400}, + {"__symbol_stub1", "__TEXT", 0x100000f81, 0xc, 0xf81, 0x0, 0x0, 0x0, 0x80000408}, + {"__stub_helper", "__TEXT", 0x100000f90, 0x18, 0xf90, 0x2, 0x0, 0x0, 0x0}, + {"__cstring", "__TEXT", 0x100000fa8, 0xd, 0xfa8, 0x0, 0x0, 0x0, 0x2}, + {"__eh_frame", "__TEXT", 0x100000fb8, 0x48, 0xfb8, 0x3, 0x0, 0x0, 0x6000000b}, + {"__data", "__DATA", 0x100001000, 0x1c, 0x1000, 0x3, 0x0, 0x0, 0x0}, + {"__dyld", "__DATA", 0x100001020, 0x38, 0x1020, 0x3, 0x0, 0x0, 0x0}, + {"__la_symbol_ptr", "__DATA", 0x100001058, 0x10, 0x1058, 0x2, 0x0, 0x0, 0x7}, }, }, { @@ -74,26 +74,26 @@ var fileTests = []fileTest{ FileHeader{0xfeedfacf, CpuAmd64, 0x80000003, 0xa, 0x4, 0x5a0, 0}, []*SegmentHeader{ nil, - &SegmentHeader{LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x0, 0x7, 0x5, 0x5, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x0, 0x0, 0x7, 0x3, 0x3, 0x0}, - &SegmentHeader{LoadCmdSegment64, 0x278, "__DWARF", 0x100002000, 0x1000, 0x1000, 0x1bc, 0x7, 0x3, 0x7, 0x0}, + {LoadCmdSegment64, 0x1d8, "__TEXT", 0x100000000, 0x1000, 0x0, 0x0, 0x7, 0x5, 0x5, 0x0}, + {LoadCmdSegment64, 0x138, "__DATA", 0x100001000, 0x1000, 0x0, 0x0, 0x7, 0x3, 0x3, 0x0}, + {LoadCmdSegment64, 0x278, "__DWARF", 0x100002000, 0x1000, 0x1000, 0x1bc, 0x7, 0x3, 0x7, 0x0}, }, []*SectionHeader{ - &SectionHeader{"__text", "__TEXT", 0x100000f14, 0x0, 0x0, 0x2, 0x0, 0x0, 0x80000400}, - &SectionHeader{"__symbol_stub1", "__TEXT", 0x100000f81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000408}, - &SectionHeader{"__stub_helper", "__TEXT", 0x100000f90, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0}, - &SectionHeader{"__cstring", "__TEXT", 0x100000fa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, - &SectionHeader{"__eh_frame", "__TEXT", 0x100000fb8, 0x0, 0x0, 0x3, 0x0, 0x0, 0x6000000b}, - &SectionHeader{"__data", "__DATA", 0x100001000, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0}, - &SectionHeader{"__dyld", "__DATA", 0x100001020, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0}, - &SectionHeader{"__la_symbol_ptr", "__DATA", 0x100001058, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7}, - &SectionHeader{"__debug_abbrev", "__DWARF", 0x100002000, 0x36, 0x1000, 0x0, 0x0, 0x0, 0x0}, - &SectionHeader{"__debug_aranges", "__DWARF", 0x100002036, 0x30, 0x1036, 0x0, 0x0, 0x0, 0x0}, - &SectionHeader{"__debug_frame", "__DWARF", 0x100002066, 0x40, 0x1066, 0x0, 0x0, 0x0, 0x0}, - &SectionHeader{"__debug_info", "__DWARF", 0x1000020a6, 0x54, 0x10a6, 0x0, 0x0, 0x0, 0x0}, - &SectionHeader{"__debug_line", "__DWARF", 0x1000020fa, 0x47, 0x10fa, 0x0, 0x0, 0x0, 0x0}, - &SectionHeader{"__debug_pubnames", "__DWARF", 0x100002141, 0x1b, 0x1141, 0x0, 0x0, 0x0, 0x0}, - &SectionHeader{"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0}, + {"__text", "__TEXT", 0x100000f14, 0x0, 0x0, 0x2, 0x0, 0x0, 0x80000400}, + {"__symbol_stub1", "__TEXT", 0x100000f81, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80000408}, + {"__stub_helper", "__TEXT", 0x100000f90, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0}, + {"__cstring", "__TEXT", 0x100000fa8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2}, + {"__eh_frame", "__TEXT", 0x100000fb8, 0x0, 0x0, 0x3, 0x0, 0x0, 0x6000000b}, + {"__data", "__DATA", 0x100001000, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0}, + {"__dyld", "__DATA", 0x100001020, 0x0, 0x0, 0x3, 0x0, 0x0, 0x0}, + {"__la_symbol_ptr", "__DATA", 0x100001058, 0x0, 0x0, 0x2, 0x0, 0x0, 0x7}, + {"__debug_abbrev", "__DWARF", 0x100002000, 0x36, 0x1000, 0x0, 0x0, 0x0, 0x0}, + {"__debug_aranges", "__DWARF", 0x100002036, 0x30, 0x1036, 0x0, 0x0, 0x0, 0x0}, + {"__debug_frame", "__DWARF", 0x100002066, 0x40, 0x1066, 0x0, 0x0, 0x0, 0x0}, + {"__debug_info", "__DWARF", 0x1000020a6, 0x54, 0x10a6, 0x0, 0x0, 0x0, 0x0}, + {"__debug_line", "__DWARF", 0x1000020fa, 0x47, 0x10fa, 0x0, 0x0, 0x0, 0x0}, + {"__debug_pubnames", "__DWARF", 0x100002141, 0x1b, 0x1141, 0x0, 0x0, 0x0, 0x0}, + {"__debug_str", "__DWARF", 0x10000215c, 0x60, 0x115c, 0x0, 0x0, 0x0, 0x0}, }, }, } diff --git a/libgo/go/debug/macho/macho.go b/libgo/go/debug/macho/macho.go index 1386f5acf57..bc14226c565 100644 --- a/libgo/go/debug/macho/macho.go +++ b/libgo/go/debug/macho/macho.go @@ -278,7 +278,7 @@ func stringName(i uint32, names []intName, goSyntax bool) string { return n.s } } - return strconv.Uitoa64(uint64(i)) + return strconv.FormatUint(uint64(i), 10) } func flagName(i uint32, names []intName, goSyntax bool) string { @@ -296,10 +296,10 @@ func flagName(i uint32, names []intName, goSyntax bool) string { } } if len(s) == 0 { - return "0x" + strconv.Uitob64(uint64(i), 16) + return "0x" + strconv.FormatUint(uint64(i), 16) } if i != 0 { - s += "+0x" + strconv.Uitob64(uint64(i), 16) + s += "+0x" + strconv.FormatUint(uint64(i), 16) } return s } diff --git a/libgo/go/debug/pe/file_test.go b/libgo/go/debug/pe/file_test.go index 2c5c25b8c41..2815d720bb6 100644 --- a/libgo/go/debug/pe/file_test.go +++ b/libgo/go/debug/pe/file_test.go @@ -20,39 +20,39 @@ var fileTests = []fileTest{ "testdata/gcc-386-mingw-obj", FileHeader{0x014c, 0x000c, 0x0, 0x64a, 0x1e, 0x0, 0x104}, []*SectionHeader{ - &SectionHeader{".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020}, - &SectionHeader{".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264}, - &SectionHeader{".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328}, - &SectionHeader{".debug_abbrev", 0, 0, 137, 536, 0, 0, 0, 0, 0x42100000}, - &SectionHeader{".debug_info", 0, 0, 418, 673, 1470, 0, 7, 0, 1108344832}, - &SectionHeader{".debug_line", 0, 0, 128, 1091, 1540, 0, 1, 0, 1108344832}, - &SectionHeader{".rdata", 0, 0, 16, 1219, 0, 0, 0, 0, 1076887616}, - &SectionHeader{".debug_frame", 0, 0, 52, 1235, 1550, 0, 2, 0, 1110441984}, - &SectionHeader{".debug_loc", 0, 0, 56, 1287, 0, 0, 0, 0, 1108344832}, - &SectionHeader{".debug_pubnames", 0, 0, 27, 1343, 1570, 0, 1, 0, 1108344832}, - &SectionHeader{".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832}, - &SectionHeader{".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832}, + {".text", 0, 0, 36, 500, 1440, 0, 3, 0, 0x60300020}, + {".data", 0, 0, 0, 0, 0, 0, 0, 0, 3224371264}, + {".bss", 0, 0, 0, 0, 0, 0, 0, 0, 3224371328}, + {".debug_abbrev", 0, 0, 137, 536, 0, 0, 0, 0, 0x42100000}, + {".debug_info", 0, 0, 418, 673, 1470, 0, 7, 0, 1108344832}, + {".debug_line", 0, 0, 128, 1091, 1540, 0, 1, 0, 1108344832}, + {".rdata", 0, 0, 16, 1219, 0, 0, 0, 0, 1076887616}, + {".debug_frame", 0, 0, 52, 1235, 1550, 0, 2, 0, 1110441984}, + {".debug_loc", 0, 0, 56, 1287, 0, 0, 0, 0, 1108344832}, + {".debug_pubnames", 0, 0, 27, 1343, 1570, 0, 1, 0, 1108344832}, + {".debug_pubtypes", 0, 0, 38, 1370, 1580, 0, 1, 0, 1108344832}, + {".debug_aranges", 0, 0, 32, 1408, 1590, 0, 2, 0, 1108344832}, }, }, { "testdata/gcc-386-mingw-exec", FileHeader{0x014c, 0x000f, 0x4c6a1b60, 0x3c00, 0x282, 0xe0, 0x107}, []*SectionHeader{ - &SectionHeader{Name: ".text", VirtualSize: 0xcd8, VirtualAddress: 0x1000, Size: 0xe00, Offset: 0x400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x60500060}, - &SectionHeader{Name: ".data", VirtualSize: 0x10, VirtualAddress: 0x2000, Size: 0x200, Offset: 0x1200, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040}, - &SectionHeader{Name: ".rdata", VirtualSize: 0x120, VirtualAddress: 0x3000, Size: 0x200, Offset: 0x1400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x40300040}, - &SectionHeader{Name: ".bss", VirtualSize: 0xdc, VirtualAddress: 0x4000, Size: 0x0, Offset: 0x0, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0400080}, - &SectionHeader{Name: ".idata", VirtualSize: 0x3c8, VirtualAddress: 0x5000, Size: 0x400, Offset: 0x1600, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040}, - &SectionHeader{Name: ".CRT", VirtualSize: 0x18, VirtualAddress: 0x6000, Size: 0x200, Offset: 0x1a00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040}, - &SectionHeader{Name: ".tls", VirtualSize: 0x20, VirtualAddress: 0x7000, Size: 0x200, Offset: 0x1c00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040}, - &SectionHeader{Name: ".debug_aranges", VirtualSize: 0x20, VirtualAddress: 0x8000, Size: 0x200, Offset: 0x1e00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, - &SectionHeader{Name: ".debug_pubnames", VirtualSize: 0x51, VirtualAddress: 0x9000, Size: 0x200, Offset: 0x2000, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, - &SectionHeader{Name: ".debug_pubtypes", VirtualSize: 0x91, VirtualAddress: 0xa000, Size: 0x200, Offset: 0x2200, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, - &SectionHeader{Name: ".debug_info", VirtualSize: 0xe22, VirtualAddress: 0xb000, Size: 0x1000, Offset: 0x2400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, - &SectionHeader{Name: ".debug_abbrev", VirtualSize: 0x157, VirtualAddress: 0xc000, Size: 0x200, Offset: 0x3400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, - &SectionHeader{Name: ".debug_line", VirtualSize: 0x144, VirtualAddress: 0xd000, Size: 0x200, Offset: 0x3600, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, - &SectionHeader{Name: ".debug_frame", VirtualSize: 0x34, VirtualAddress: 0xe000, Size: 0x200, Offset: 0x3800, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42300000}, - &SectionHeader{Name: ".debug_loc", VirtualSize: 0x38, VirtualAddress: 0xf000, Size: 0x200, Offset: 0x3a00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, + {Name: ".text", VirtualSize: 0xcd8, VirtualAddress: 0x1000, Size: 0xe00, Offset: 0x400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x60500060}, + {Name: ".data", VirtualSize: 0x10, VirtualAddress: 0x2000, Size: 0x200, Offset: 0x1200, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040}, + {Name: ".rdata", VirtualSize: 0x120, VirtualAddress: 0x3000, Size: 0x200, Offset: 0x1400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x40300040}, + {Name: ".bss", VirtualSize: 0xdc, VirtualAddress: 0x4000, Size: 0x0, Offset: 0x0, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0400080}, + {Name: ".idata", VirtualSize: 0x3c8, VirtualAddress: 0x5000, Size: 0x400, Offset: 0x1600, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040}, + {Name: ".CRT", VirtualSize: 0x18, VirtualAddress: 0x6000, Size: 0x200, Offset: 0x1a00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040}, + {Name: ".tls", VirtualSize: 0x20, VirtualAddress: 0x7000, Size: 0x200, Offset: 0x1c00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0xc0300040}, + {Name: ".debug_aranges", VirtualSize: 0x20, VirtualAddress: 0x8000, Size: 0x200, Offset: 0x1e00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, + {Name: ".debug_pubnames", VirtualSize: 0x51, VirtualAddress: 0x9000, Size: 0x200, Offset: 0x2000, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, + {Name: ".debug_pubtypes", VirtualSize: 0x91, VirtualAddress: 0xa000, Size: 0x200, Offset: 0x2200, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, + {Name: ".debug_info", VirtualSize: 0xe22, VirtualAddress: 0xb000, Size: 0x1000, Offset: 0x2400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, + {Name: ".debug_abbrev", VirtualSize: 0x157, VirtualAddress: 0xc000, Size: 0x200, Offset: 0x3400, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, + {Name: ".debug_line", VirtualSize: 0x144, VirtualAddress: 0xd000, Size: 0x200, Offset: 0x3600, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, + {Name: ".debug_frame", VirtualSize: 0x34, VirtualAddress: 0xe000, Size: 0x200, Offset: 0x3800, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42300000}, + {Name: ".debug_loc", VirtualSize: 0x38, VirtualAddress: 0xf000, Size: 0x200, Offset: 0x3a00, PointerToRelocations: 0x0, PointerToLineNumbers: 0x0, NumberOfRelocations: 0x0, NumberOfLineNumbers: 0x0, Characteristics: 0x42100000}, }, }, } diff --git a/libgo/go/encoding/ascii85/ascii85.go b/libgo/go/encoding/ascii85/ascii85.go index 6f592f3d727..7d004b5e5d7 100644 --- a/libgo/go/encoding/ascii85/ascii85.go +++ b/libgo/go/encoding/ascii85/ascii85.go @@ -168,7 +168,7 @@ func (e *encoder) Close() error { type CorruptInputError int64 func (e CorruptInputError) Error() string { - return "illegal ascii85 data at input byte " + strconv.Itoa64(int64(e)) + return "illegal ascii85 data at input byte " + strconv.FormatInt(int64(e), 10) } // Decode decodes src into dst, returning both the number diff --git a/libgo/go/encoding/asn1/asn1_test.go b/libgo/go/encoding/asn1/asn1_test.go index 2e6fccf7b80..09f94139f90 100644 --- a/libgo/go/encoding/asn1/asn1_test.go +++ b/libgo/go/encoding/asn1/asn1_test.go @@ -225,19 +225,19 @@ func TestUTCTime(t *testing.T) { ret, err := parseUTCTime([]byte(test.in)) if err != nil { if test.ok { - t.Errorf("#%d: parseUTCTime(%q) = error %v", i, err) + t.Errorf("#%d: parseUTCTime(%q) = error %v", i, test.in, err) } continue } if !test.ok { - t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i) + t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i, test.in) continue } const format = "Jan _2 15:04:05 -0700 2006" // ignore zone name, just offset have := ret.Format(format) want := test.out.Format(format) if have != want { - t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", test.in, have, want) + t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", i, test.in, have, want) } } } diff --git a/libgo/go/encoding/asn1/common.go b/libgo/go/encoding/asn1/common.go index 01f4f7b6ec7..f7cb3acbb86 100644 --- a/libgo/go/encoding/asn1/common.go +++ b/libgo/go/encoding/asn1/common.go @@ -98,7 +98,7 @@ func parseFieldParameters(str string) (ret fieldParameters) { case part == "printable": ret.stringType = tagPrintableString case strings.HasPrefix(part, "default:"): - i, err := strconv.Atoi64(part[8:]) + i, err := strconv.ParseInt(part[8:], 10, 64) if err == nil { ret.defaultValue = new(int64) *ret.defaultValue = i diff --git a/libgo/go/encoding/base32/base32.go b/libgo/go/encoding/base32/base32.go index 494c760d87d..c75c7c19d15 100644 --- a/libgo/go/encoding/base32/base32.go +++ b/libgo/go/encoding/base32/base32.go @@ -216,7 +216,7 @@ func (enc *Encoding) EncodedLen(n int) int { return (n + 4) / 5 * 8 } type CorruptInputError int64 func (e CorruptInputError) Error() string { - return "illegal base32 data at input byte " + strconv.Itoa64(int64(e)) + return "illegal base32 data at input byte " + strconv.FormatInt(int64(e), 10) } // decode is like Decode but returns an additional 'end' value, which diff --git a/libgo/go/encoding/base64/base64.go b/libgo/go/encoding/base64/base64.go index 945128947ab..889b565e3f5 100644 --- a/libgo/go/encoding/base64/base64.go +++ b/libgo/go/encoding/base64/base64.go @@ -203,7 +203,7 @@ func (enc *Encoding) EncodedLen(n int) int { return (n + 2) / 3 * 4 } type CorruptInputError int64 func (e CorruptInputError) Error() string { - return "illegal base64 data at input byte " + strconv.Itoa64(int64(e)) + return "illegal base64 data at input byte " + strconv.FormatInt(int64(e), 10) } // decode is like Decode but returns an additional 'end' value, which diff --git a/libgo/go/encoding/git85/git.go b/libgo/go/encoding/git85/git.go index b6ad6e2dd38..d383213ce87 100644 --- a/libgo/go/encoding/git85/git.go +++ b/libgo/go/encoding/git85/git.go @@ -15,7 +15,7 @@ import ( type CorruptInputError int64 func (e CorruptInputError) Error() string { - return "illegal git85 data at input byte " + strconv.Itoa64(int64(e)) + return "illegal git85 data at input byte " + strconv.FormatInt(int64(e), 10) } const encode = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~" diff --git a/libgo/go/encoding/gob/encoder.go b/libgo/go/encoding/gob/encoder.go index e4a48dfc4fc..a15b5a1f9a1 100644 --- a/libgo/go/encoding/gob/encoder.go +++ b/libgo/go/encoding/gob/encoder.go @@ -119,7 +119,9 @@ func (enc *Encoder) sendActualType(w io.Writer, state *encoderState, ut *userTyp switch st := actual; st.Kind() { case reflect.Struct: for i := 0; i < st.NumField(); i++ { - enc.sendType(w, state, st.Field(i).Type) + if isExported(st.Field(i).Name) { + enc.sendType(w, state, st.Field(i).Type) + } } case reflect.Array, reflect.Slice: enc.sendType(w, state, st.Elem()) diff --git a/libgo/go/encoding/gob/encoder_test.go b/libgo/go/encoding/gob/encoder_test.go index bc5af120af3..5bc957bb370 100644 --- a/libgo/go/encoding/gob/encoder_test.go +++ b/libgo/go/encoding/gob/encoder_test.go @@ -662,3 +662,19 @@ func TestSequentialDecoder(t *testing.T) { } } } + +// Should be able to have unrepresentable fields (chan, func) as long as they +// are unexported. +type Bug2 struct { + A int + b chan int +} + +func TestUnexportedChan(t *testing.T) { + b := Bug2{23, make(chan int)} + var stream bytes.Buffer + enc := NewEncoder(&stream) + if err := enc.Encode(b); err != nil { + t.Fatalf("error encoding unexported channel: %s", err) + } +} diff --git a/libgo/go/encoding/json/decode.go b/libgo/go/encoding/json/decode.go index 2ea06c50c27..0a700926296 100644 --- a/libgo/go/encoding/json/decode.go +++ b/libgo/go/encoding/json/decode.go @@ -642,7 +642,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value) { default: d.error(&UnmarshalTypeError{"number", v.Type()}) case reflect.Interface: - n, err := strconv.Atof64(s) + n, err := strconv.ParseFloat(s, 64) if err != nil { d.saveError(&UnmarshalTypeError{"number " + s, v.Type()}) break @@ -650,7 +650,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value) { v.Set(reflect.ValueOf(n)) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - n, err := strconv.Atoi64(s) + n, err := strconv.ParseInt(s, 10, 64) if err != nil || v.OverflowInt(n) { d.saveError(&UnmarshalTypeError{"number " + s, v.Type()}) break @@ -658,7 +658,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value) { v.SetInt(n) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - n, err := strconv.Atoui64(s) + n, err := strconv.ParseUint(s, 10, 64) if err != nil || v.OverflowUint(n) { d.saveError(&UnmarshalTypeError{"number " + s, v.Type()}) break @@ -666,7 +666,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value) { v.SetUint(n) case reflect.Float32, reflect.Float64: - n, err := strconv.AtofN(s, v.Type().Bits()) + n, err := strconv.ParseFloat(s, v.Type().Bits()) if err != nil || v.OverflowFloat(n) { d.saveError(&UnmarshalTypeError{"number " + s, v.Type()}) break @@ -798,7 +798,7 @@ func (d *decodeState) literalInterface() interface{} { if c != '-' && (c < '0' || c > '9') { d.error(errPhase) } - n, err := strconv.Atof64(string(item)) + n, err := strconv.ParseFloat(string(item), 64) if err != nil { d.saveError(&UnmarshalTypeError{"number " + string(item), reflect.TypeOf(0.0)}) } @@ -813,7 +813,7 @@ func getu4(s []byte) rune { if len(s) < 6 || s[0] != '\\' || s[1] != 'u' { return -1 } - r, err := strconv.Btoui64(string(s[2:6]), 16) + r, err := strconv.ParseUint(string(s[2:6]), 16, 64) if err != nil { return -1 } diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go index bd4326a0cd7..bf3953eb051 100644 --- a/libgo/go/encoding/json/decode_test.go +++ b/libgo/go/encoding/json/decode_test.go @@ -345,12 +345,12 @@ var allValue = All{ "18": {Tag: "tag18"}, }, MapP: map[string]*Small{ - "19": &Small{Tag: "tag19"}, + "19": {Tag: "tag19"}, "20": nil, }, EmptyMap: map[string]Small{}, Slice: []Small{{Tag: "tag20"}, {Tag: "tag21"}}, - SliceP: []*Small{&Small{Tag: "tag22"}, nil, &Small{Tag: "tag23"}}, + SliceP: []*Small{{Tag: "tag22"}, nil, {Tag: "tag23"}}, EmptySlice: []Small{}, StringSlice: []string{"str24", "str25", "str26"}, ByteSlice: []byte{27, 28, 29}, diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go index 14284f50e47..69deaf2a40d 100644 --- a/libgo/go/encoding/json/encode.go +++ b/libgo/go/encoding/json/encode.go @@ -275,13 +275,13 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) { } case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - writeString(e, strconv.Itoa64(v.Int())) + writeString(e, strconv.FormatInt(v.Int(), 10)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - writeString(e, strconv.Uitoa64(v.Uint())) + writeString(e, strconv.FormatUint(v.Uint(), 10)) case reflect.Float32, reflect.Float64: - writeString(e, strconv.FtoaN(v.Float(), 'g', -1, v.Type().Bits())) + writeString(e, strconv.FormatFloat(v.Float(), 'g', -1, v.Type().Bits())) case reflect.String: if quoted { diff --git a/libgo/go/encoding/xml/marshal.go b/libgo/go/encoding/xml/marshal.go index 691b70d2510..e94fdbc531f 100644 --- a/libgo/go/encoding/xml/marshal.go +++ b/libgo/go/encoding/xml/marshal.go @@ -173,15 +173,15 @@ func (p *printer) marshalValue(val reflect.Value, name string) error { switch k := val.Kind(); k { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - p.WriteString(strconv.Itoa64(val.Int())) + p.WriteString(strconv.FormatInt(val.Int(), 10)) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: - p.WriteString(strconv.Uitoa64(val.Uint())) + p.WriteString(strconv.FormatUint(val.Uint(), 10)) case reflect.Float32, reflect.Float64: - p.WriteString(strconv.Ftoa64(val.Float(), 'g', -1)) + p.WriteString(strconv.FormatFloat(val.Float(), 'g', -1, 64)) case reflect.String: Escape(p, []byte(val.String())) case reflect.Bool: - p.WriteString(strconv.Btoa(val.Bool())) + p.WriteString(strconv.FormatBool(val.Bool())) case reflect.Array: // will be [...]byte bytes := make([]byte, val.Len()) diff --git a/libgo/go/encoding/xml/marshal_test.go b/libgo/go/encoding/xml/marshal_test.go index a6f7d2d0c27..80407658015 100644 --- a/libgo/go/encoding/xml/marshal_test.go +++ b/libgo/go/encoding/xml/marshal_test.go @@ -160,19 +160,19 @@ var marshalTests = []struct { Age: 1, Drive: ImprobabilityDrive, Passenger: []*Passenger{ - &Passenger{ + { Name: []string{"Zaphod", "Beeblebrox"}, Weight: 7.25, }, - &Passenger{ + { Name: []string{"Trisha", "McMillen"}, Weight: 5.5, }, - &Passenger{ + { Name: []string{"Ford", "Prefect"}, Weight: 7, }, - &Passenger{ + { Name: []string{"Arthur", "Dent"}, Weight: 6.75, }, @@ -326,12 +326,12 @@ var marshalErrorTests = []struct { "question": "What do you get when you multiply six by nine?", "answer": "42", }, - Err: "xml: unsupported type: map[string] string", + Err: "xml: unsupported type: map[string]string", Kind: reflect.Map, }, { Value: map[*Ship]bool{nil: false}, - Err: "xml: unsupported type: map[*xml.Ship] bool", + Err: "xml: unsupported type: map[*xml.Ship]bool", Kind: reflect.Map, }, } diff --git a/libgo/go/encoding/xml/read.go b/libgo/go/encoding/xml/read.go index c6a3d75a801..6dd36541000 100644 --- a/libgo/go/encoding/xml/read.go +++ b/libgo/go/encoding/xml/read.go @@ -486,19 +486,19 @@ func copyValue(dst reflect.Value, src []byte) (err error) { // Helper functions for integer and unsigned integer conversions var itmp int64 getInt64 := func() bool { - itmp, err = strconv.Atoi64(string(src)) + itmp, err = strconv.ParseInt(string(src), 10, 64) // TODO: should check sizes return err == nil } var utmp uint64 getUint64 := func() bool { - utmp, err = strconv.Atoui64(string(src)) + utmp, err = strconv.ParseUint(string(src), 10, 64) // TODO: check for overflow? return err == nil } var ftmp float64 getFloat64 := func() bool { - ftmp, err = strconv.Atof64(string(src)) + ftmp, err = strconv.ParseFloat(string(src), 64) // TODO: check for overflow? return err == nil } @@ -525,7 +525,7 @@ func copyValue(dst reflect.Value, src []byte) (err error) { } t.SetFloat(ftmp) case reflect.Bool: - value, err := strconv.Atob(strings.TrimSpace(string(src))) + value, err := strconv.ParseBool(strings.TrimSpace(string(src))) if err != nil { return err } diff --git a/libgo/go/encoding/xml/xml.go b/libgo/go/encoding/xml/xml.go index d67a299f5bb..d001c408923 100644 --- a/libgo/go/encoding/xml/xml.go +++ b/libgo/go/encoding/xml/xml.go @@ -889,9 +889,9 @@ Input: var n uint64 var err error if i >= 3 && s[1] == 'x' { - n, err = strconv.Btoui64(s[2:], 16) + n, err = strconv.ParseUint(s[2:], 16, 64) } else { - n, err = strconv.Btoui64(s[1:], 10) + n, err = strconv.ParseUint(s[1:], 10, 64) } if err == nil && n <= unicode.MaxRune { text = string(n) diff --git a/libgo/go/exp/norm/maketables.go b/libgo/go/exp/norm/maketables.go index 39bab7f0b6a..9a97831716b 100644 --- a/libgo/go/exp/norm/maketables.go +++ b/libgo/go/exp/norm/maketables.go @@ -226,7 +226,7 @@ func parseDecomposition(s string, skipfirst bool) (a []rune, e error) { decomp = decomp[1:] } for _, d := range decomp { - point, err := strconv.Btoui64(d, 16) + point, err := strconv.ParseUint(d, 16, 64) if err != nil { return a, err } @@ -240,7 +240,7 @@ func parseCharacter(line string) { if len(field) != NumField { logger.Fatalf("%5s: %d fields (expected %d)\n", line, len(field), NumField) } - x, err := strconv.Btoui64(field[FCodePoint], 16) + x, err := strconv.ParseUint(field[FCodePoint], 16, 64) point := int(x) if err != nil { logger.Fatalf("%.5s...: %s", line, err) @@ -264,7 +264,7 @@ func parseCharacter(line string) { if state != SLast { firstChar = lastChar } - x, err = strconv.Atoui64(field[FCanonicalCombiningClass]) + x, err = strconv.ParseUint(field[FCanonicalCombiningClass], 10, 64) if err != nil { logger.Fatalf("%U: bad ccc field: %s", int(x), err) } @@ -336,7 +336,7 @@ func parseExclusion(line string) int { if len(matches) != 2 { logger.Fatalf("%s: %d matches (expected 1)\n", line, len(matches)) } - point, err := strconv.Btoui64(matches[1], 16) + point, err := strconv.ParseUint(matches[1], 16, 64) if err != nil { logger.Fatalf("%.5s...: %s", line, err) } @@ -792,13 +792,13 @@ func testDerived() { continue } rng := strings.Split(qc[1], "..") - i, err := strconv.Btoui64(rng[0], 16) + i, err := strconv.ParseUint(rng[0], 16, 64) if err != nil { log.Fatal(err) } j := i if len(rng) > 1 { - j, err = strconv.Btoui64(rng[1], 16) + j, err = strconv.ParseUint(rng[1], 16, 64) if err != nil { log.Fatal(err) } diff --git a/libgo/go/exp/norm/normregtest.go b/libgo/go/exp/norm/normregtest.go index 6610c257e51..d214ce11bc2 100644 --- a/libgo/go/exp/norm/normregtest.go +++ b/libgo/go/exp/norm/normregtest.go @@ -171,7 +171,7 @@ func loadTestData() { counter++ for j := 1; j < len(m)-1; j++ { for _, split := range strings.Split(m[j], " ") { - r, err := strconv.Btoui64(split, 16) + r, err := strconv.ParseUint(split, 16, 64) if err != nil { logger.Fatal(err) } diff --git a/libgo/go/exp/sql/convert.go b/libgo/go/exp/sql/convert.go index 48e281203be..24315a0d351 100644 --- a/libgo/go/exp/sql/convert.go +++ b/libgo/go/exp/sql/convert.go @@ -95,7 +95,7 @@ func convertAssign(dest, src interface{}) error { switch dv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: s := asString(src) - i64, err := strconv.Atoi64(s) + i64, err := strconv.ParseInt(s, 10, 64) if err != nil { return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) } @@ -106,7 +106,7 @@ func convertAssign(dest, src interface{}) error { return nil case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: s := asString(src) - u64, err := strconv.Atoui64(s) + u64, err := strconv.ParseUint(s, 10, 64) if err != nil { return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) } @@ -117,7 +117,7 @@ func convertAssign(dest, src interface{}) error { return nil case reflect.Float32, reflect.Float64: s := asString(src) - f64, err := strconv.Atof64(s) + f64, err := strconv.ParseFloat(s, 64) if err != nil { return fmt.Errorf("converting string %q to a %s: %v", s, dv.Kind(), err) } diff --git a/libgo/go/exp/sql/driver/types.go b/libgo/go/exp/sql/driver/types.go index 6e0ce4339cc..086b529c84f 100644 --- a/libgo/go/exp/sql/driver/types.go +++ b/libgo/go/exp/sql/driver/types.go @@ -54,13 +54,13 @@ func (boolType) ConvertValue(src interface{}) (interface{}, error) { case bool: return s, nil case string: - b, err := strconv.Atob(s) + b, err := strconv.ParseBool(s) if err != nil { return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s) } return b, nil case []byte: - b, err := strconv.Atob(string(s)) + b, err := strconv.ParseBool(string(s)) if err != nil { return nil, fmt.Errorf("sql/driver: couldn't convert %q into type bool", s) } diff --git a/libgo/go/exp/ssh/cipher.go b/libgo/go/exp/ssh/cipher.go index de4926d7b81..d91929aa99a 100644 --- a/libgo/go/exp/ssh/cipher.go +++ b/libgo/go/exp/ssh/cipher.go @@ -77,12 +77,12 @@ var DefaultCipherOrder = []string{ var cipherModes = map[string]*cipherMode{ // Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms // are defined in the order specified in the RFC. - "aes128-ctr": &cipherMode{16, aes.BlockSize, 0, newAESCTR}, - "aes192-ctr": &cipherMode{24, aes.BlockSize, 0, newAESCTR}, - "aes256-ctr": &cipherMode{32, aes.BlockSize, 0, newAESCTR}, + "aes128-ctr": {16, aes.BlockSize, 0, newAESCTR}, + "aes192-ctr": {24, aes.BlockSize, 0, newAESCTR}, + "aes256-ctr": {32, aes.BlockSize, 0, newAESCTR}, // Ciphers from RFC4345, which introduces security-improved arcfour ciphers. // They are defined in the order specified in the RFC. - "arcfour128": &cipherMode{16, 0, 1536, newRC4}, - "arcfour256": &cipherMode{32, 0, 1536, newRC4}, + "arcfour128": {16, 0, 1536, newRC4}, + "arcfour256": {32, 0, 1536, newRC4}, } diff --git a/libgo/go/exp/ssh/client.go b/libgo/go/exp/ssh/client.go index 429dee975bc..d89b908cdcf 100644 --- a/libgo/go/exp/ssh/client.go +++ b/libgo/go/exp/ssh/client.go @@ -200,7 +200,7 @@ func (c *ClientConn) mainLoop() { peersId := uint32(packet[1])<<24 | uint32(packet[2])<<16 | uint32(packet[3])<<8 | uint32(packet[4]) if length := int(packet[5])<<24 | int(packet[6])<<16 | int(packet[7])<<8 | int(packet[8]); length > 0 { packet = packet[9:] - c.getChan(peersId).data <- packet[:length] + c.getChan(peersId).stdout.data <- packet[:length] } case msgChannelExtendedData: if len(packet) < 13 { @@ -215,7 +215,7 @@ func (c *ClientConn) mainLoop() { // for stderr on interactive sessions. Other data types are // silently discarded. if datatype == 1 { - c.getChan(peersId).dataExt <- packet[:length] + c.getChan(peersId).stderr.data <- packet[:length] } } default: @@ -228,9 +228,9 @@ func (c *ClientConn) mainLoop() { c.getChan(msg.PeersId).msg <- msg case *channelCloseMsg: ch := c.getChan(msg.PeersId) - close(ch.win) - close(ch.data) - close(ch.dataExt) + close(ch.stdin.win) + close(ch.stdout.data) + close(ch.stderr.data) c.chanlist.remove(msg.PeersId) case *channelEOFMsg: c.getChan(msg.PeersId).msg <- msg @@ -241,7 +241,7 @@ func (c *ClientConn) mainLoop() { case *channelRequestMsg: c.getChan(msg.PeersId).msg <- msg case *windowAdjustMsg: - c.getChan(msg.PeersId).win <- int(msg.AdditionalBytes) + c.getChan(msg.PeersId).stdin.win <- int(msg.AdditionalBytes) default: fmt.Printf("mainLoop: unhandled message %T: %v\n", msg, msg) } @@ -290,21 +290,49 @@ func (c *ClientConfig) rand() io.Reader { type clientChan struct { packetWriter id, peersId uint32 - data chan []byte // receives the payload of channelData messages - dataExt chan []byte // receives the payload of channelExtendedData messages - win chan int // receives window adjustments + stdin *chanWriter // receives window adjustments + stdout *chanReader // receives the payload of channelData messages + stderr *chanReader // receives the payload of channelExtendedData messages msg chan interface{} // incoming messages } +// newClientChan returns a partially constructed *clientChan +// using the local id provided. To be usable clientChan.peersId +// needs to be assigned once known. func newClientChan(t *transport, id uint32) *clientChan { - return &clientChan{ + c := &clientChan{ packetWriter: t, id: id, - data: make(chan []byte, 16), - dataExt: make(chan []byte, 16), - win: make(chan int, 16), msg: make(chan interface{}, 16), } + c.stdin = &chanWriter{ + win: make(chan int, 16), + clientChan: c, + } + c.stdout = &chanReader{ + data: make(chan []byte, 16), + clientChan: c, + } + c.stderr = &chanReader{ + data: make(chan []byte, 16), + clientChan: c, + } + return c +} + +// waitForChannelOpenResponse, if successful, fills out +// the peerId and records any initial window advertisement. +func (c *clientChan) waitForChannelOpenResponse() error { + switch msg := (<-c.msg).(type) { + case *channelOpenConfirmMsg: + // fixup peersId field + c.peersId = msg.MyId + c.stdin.win <- int(msg.MyWindow) + return nil + case *channelOpenFailureMsg: + return errors.New(safeString(msg.Message)) + } + return errors.New("unexpected packet") } // Close closes the channel. This does not close the underlying connection. @@ -355,10 +383,9 @@ func (c *chanlist) remove(id uint32) { // A chanWriter represents the stdin of a remote process. type chanWriter struct { - win chan int // receives window adjustments - peersId uint32 // the peer's id - rwin int // current rwin size - packetWriter // for sending channelDataMsg + win chan int // receives window adjustments + rwin int // current rwin size + clientChan *clientChan // the channel backing this writer } // Write writes data to the remote process's standard input. @@ -372,12 +399,13 @@ func (w *chanWriter) Write(data []byte) (n int, err error) { w.rwin += win continue } + peersId := w.clientChan.peersId n = len(data) packet := make([]byte, 0, 9+n) packet = append(packet, msgChannelData, - byte(w.peersId>>24), byte(w.peersId>>16), byte(w.peersId>>8), byte(w.peersId), + byte(peersId>>24), byte(peersId>>16), byte(peersId>>8), byte(peersId), byte(n>>24), byte(n>>16), byte(n>>8), byte(n)) - err = w.writePacket(append(packet, data...)) + err = w.clientChan.writePacket(append(packet, data...)) w.rwin -= n return } @@ -385,7 +413,7 @@ func (w *chanWriter) Write(data []byte) (n int, err error) { } func (w *chanWriter) Close() error { - return w.writePacket(marshal(msgChannelEOF, channelEOFMsg{w.peersId})) + return w.clientChan.writePacket(marshal(msgChannelEOF, channelEOFMsg{w.clientChan.peersId})) } // A chanReader represents stdout or stderr of a remote process. @@ -393,10 +421,9 @@ type chanReader struct { // TODO(dfc) a fixed size channel may not be the right data structure. // If writes to this channel block, they will block mainLoop, making // it unable to receive new messages from the remote side. - data chan []byte // receives data from remote - peersId uint32 // the peer's id - packetWriter // for sending windowAdjustMsg - buf []byte + data chan []byte // receives data from remote + clientChan *clientChan // the channel backing this reader + buf []byte } // Read reads data from the remote process's stdout or stderr. @@ -407,10 +434,10 @@ func (r *chanReader) Read(data []byte) (int, error) { n := copy(data, r.buf) r.buf = r.buf[n:] msg := windowAdjustMsg{ - PeersId: r.peersId, + PeersId: r.clientChan.peersId, AdditionalBytes: uint32(n), } - return n, r.writePacket(marshal(msgChannelWindowAdjust, msg)) + return n, r.clientChan.writePacket(marshal(msgChannelWindowAdjust, msg)) } r.buf, ok = <-r.data if !ok { diff --git a/libgo/go/exp/ssh/client_auth.go b/libgo/go/exp/ssh/client_auth.go index 25f9e216225..1a382357b46 100644 --- a/libgo/go/exp/ssh/client_auth.go +++ b/libgo/go/exp/ssh/client_auth.go @@ -9,7 +9,7 @@ import ( "io" ) -// authenticate authenticates with the remote server. See RFC 4252. +// authenticate authenticates with the remote server. See RFC 4252. func (c *ClientConn) authenticate(session []byte) error { // initiate user auth session if err := c.writePacket(marshal(msgServiceRequest, serviceRequestMsg{serviceUserAuth})); err != nil { @@ -24,7 +24,7 @@ func (c *ClientConn) authenticate(session []byte) error { return err } // during the authentication phase the client first attempts the "none" method - // then any untried methods suggested by the server. + // then any untried methods suggested by the server. tried, remain := make(map[string]bool), make(map[string]bool) for auth := ClientAuth(new(noneAuth)); auth != nil; { ok, methods, err := auth.auth(session, c.config.User, c.transport, c.config.rand()) @@ -57,9 +57,9 @@ func (c *ClientConn) authenticate(session []byte) error { // A ClientAuth represents an instance of an RFC 4252 authentication method. type ClientAuth interface { - // auth authenticates user over transport t. + // auth authenticates user over transport t. // Returns true if authentication is successful. - // If authentication is not successful, a []string of alternative + // If authentication is not successful, a []string of alternative // method names is returned. auth(session []byte, user string, t *transport, rand io.Reader) (bool, []string, error) @@ -79,19 +79,7 @@ func (n *noneAuth) auth(session []byte, user string, t *transport, rand io.Reade return false, nil, err } - packet, err := t.readPacket() - if err != nil { - return false, nil, err - } - - switch packet[0] { - case msgUserAuthSuccess: - return true, nil, nil - case msgUserAuthFailure: - msg := decode(packet).(*userAuthFailureMsg) - return false, msg.Methods, nil - } - return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]} + return handleAuthResponse(t) } func (n *noneAuth) method() string { @@ -127,19 +115,7 @@ func (p *passwordAuth) auth(session []byte, user string, t *transport, rand io.R return false, nil, err } - packet, err := t.readPacket() - if err != nil { - return false, nil, err - } - - switch packet[0] { - case msgUserAuthSuccess: - return true, nil, nil - case msgUserAuthFailure: - msg := decode(packet).(*userAuthFailureMsg) - return false, msg.Methods, nil - } - return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]} + return handleAuthResponse(t) } func (p *passwordAuth) method() string { @@ -159,7 +135,7 @@ func ClientAuthPassword(impl ClientPassword) ClientAuth { // ClientKeyring implements access to a client key ring. type ClientKeyring interface { - // Key returns the i'th rsa.Publickey or dsa.Publickey, or nil if + // Key returns the i'th rsa.Publickey or dsa.Publickey, or nil if // no key exists at i. Key(i int) (key interface{}, err error) @@ -173,27 +149,28 @@ type publickeyAuth struct { ClientKeyring } +type publickeyAuthMsg struct { + User string + Service string + Method string + // HasSig indicates to the reciver packet that the auth request is signed and + // should be used for authentication of the request. + HasSig bool + Algoname string + Pubkey string + // Sig is defined as []byte so marshal will exclude it during validateKey + Sig []byte `ssh:"rest"` +} + func (p *publickeyAuth) auth(session []byte, user string, t *transport, rand io.Reader) (bool, []string, error) { - type publickeyAuthMsg struct { - User string - Service string - Method string - // HasSig indicates to the reciver packet that the auth request is signed and - // should be used for authentication of the request. - HasSig bool - Algoname string - Pubkey string - // Sig is defined as []byte so marshal will exclude it during the query phase - Sig []byte `ssh:"rest"` - } // Authentication is performed in two stages. The first stage sends an // enquiry to test if each key is acceptable to the remote. The second - // stage attempts to authenticate with the valid keys obtained in the + // stage attempts to authenticate with the valid keys obtained in the // first stage. var index int - // a map of public keys to their index in the keyring + // a map of public keys to their index in the keyring validKeys := make(map[int]interface{}) for { key, err := p.Key(index) @@ -204,33 +181,13 @@ func (p *publickeyAuth) auth(session []byte, user string, t *transport, rand io. // no more keys in the keyring break } - pubkey := serializePublickey(key) - algoname := algoName(key) - msg := publickeyAuthMsg{ - User: user, - Service: serviceSSH, - Method: p.method(), - HasSig: false, - Algoname: algoname, - Pubkey: string(pubkey), - } - if err := t.writePacket(marshal(msgUserAuthRequest, msg)); err != nil { - return false, nil, err - } - packet, err := t.readPacket() - if err != nil { - return false, nil, err - } - switch packet[0] { - case msgUserAuthPubKeyOk: - msg := decode(packet).(*userAuthPubKeyOkMsg) - if msg.Algo != algoname || msg.PubKey != string(pubkey) { - continue - } + + if ok, err := p.validateKey(key, user, t); ok { validKeys[index] = key - case msgUserAuthFailure: - default: - return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]} + } else { + if err != nil { + return false, nil, err + } } index++ } @@ -265,24 +222,61 @@ func (p *publickeyAuth) auth(session []byte, user string, t *transport, rand io. if err := t.writePacket(p); err != nil { return false, nil, err } - packet, err := t.readPacket() + success, methods, err := handleAuthResponse(t) if err != nil { return false, nil, err } + if success { + return success, methods, err + } + } + return false, methods, nil +} + +// validateKey validates the key provided it is acceptable to the server. +func (p *publickeyAuth) validateKey(key interface{}, user string, t *transport) (bool, error) { + pubkey := serializePublickey(key) + algoname := algoName(key) + msg := publickeyAuthMsg{ + User: user, + Service: serviceSSH, + Method: p.method(), + HasSig: false, + Algoname: algoname, + Pubkey: string(pubkey), + } + if err := t.writePacket(marshal(msgUserAuthRequest, msg)); err != nil { + return false, err + } + + return p.confirmKeyAck(key, t) +} + +func (p *publickeyAuth) confirmKeyAck(key interface{}, t *transport) (bool, error) { + pubkey := serializePublickey(key) + algoname := algoName(key) + + for { + packet, err := t.readPacket() + if err != nil { + return false, err + } switch packet[0] { - case msgUserAuthSuccess: - return true, nil, nil + case msgUserAuthBanner: + // TODO(gpaul): add callback to present the banner to the user + case msgUserAuthPubKeyOk: + msg := decode(packet).(*userAuthPubKeyOkMsg) + if msg.Algo != algoname || msg.PubKey != string(pubkey) { + return false, nil + } + return true, nil case msgUserAuthFailure: - msg := decode(packet).(*userAuthFailureMsg) - methods = msg.Methods - continue - case msgDisconnect: - return false, nil, io.EOF + return false, nil default: - return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]} + return false, UnexpectedMessageError{msgUserAuthSuccess, packet[0]} } } - return false, methods, nil + panic("unreachable") } func (p *publickeyAuth) method() string { @@ -293,3 +287,30 @@ func (p *publickeyAuth) method() string { func ClientAuthPublickey(impl ClientKeyring) ClientAuth { return &publickeyAuth{impl} } + +// handleAuthResponse returns whether the preceding authentication request succeeded +// along with a list of remaining authentication methods to try next and +// an error if an unexpected response was received. +func handleAuthResponse(t *transport) (bool, []string, error) { + for { + packet, err := t.readPacket() + if err != nil { + return false, nil, err + } + + switch packet[0] { + case msgUserAuthBanner: + // TODO: add callback to present the banner to the user + case msgUserAuthFailure: + msg := decode(packet).(*userAuthFailureMsg) + return false, msg.Methods, nil + case msgUserAuthSuccess: + return true, nil, nil + case msgDisconnect: + return false, nil, io.EOF + default: + return false, nil, UnexpectedMessageError{msgUserAuthSuccess, packet[0]} + } + } + panic("unreachable") +} diff --git a/libgo/go/exp/ssh/client_auth_test.go b/libgo/go/exp/ssh/client_auth_test.go index 4ef9213a9cd..2b89e9728c7 100644 --- a/libgo/go/exp/ssh/client_auth_test.go +++ b/libgo/go/exp/ssh/client_auth_test.go @@ -7,17 +7,20 @@ package ssh import ( "bytes" "crypto" - "crypto/rand" + "crypto/dsa" "crypto/rsa" + _ "crypto/sha1" "crypto/x509" "encoding/pem" "errors" "io" "io/ioutil" + "math/big" "testing" ) -const _pem = `-----BEGIN RSA PRIVATE KEY----- +// private key for mock server +const testServerPrivateKey = `-----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA19lGVsTqIT5iiNYRgnoY1CwkbETW5cq+Rzk5v/kTlf31XpSU 70HVWkbTERECjaYdXM2gGcbb+sxpq6GtXf1M3kVomycqhxwhPv4Cr6Xp4WT/jkFx 9z+FFzpeodGJWjOH6L2H5uX1Cvr9EDdQp9t9/J32/qBFntY8GwoUI/y/1MSTmMiF @@ -45,25 +48,32 @@ gqnBycHj6AhEycjda75cs+0zybZvN4x65KZHOGW/O/7OAWEcZP5TPb3zf9ned3Hl NsZoFj52ponUM6+99A2CmezFCN16c4mbA//luWF+k3VVqR6BpkrhKw== -----END RSA PRIVATE KEY-----` -// reused internally by tests -var serverConfig = new(ServerConfig) - -func init() { - if err := serverConfig.SetRSAPrivateKey([]byte(_pem)); err != nil { - panic("unable to set private key: " + err.Error()) - } -} +const testClientPrivateKey = `-----BEGIN RSA PRIVATE KEY----- +MIIBOwIBAAJBALdGZxkXDAjsYk10ihwU6Id2KeILz1TAJuoq4tOgDWxEEGeTrcld +r/ZwVaFzjWzxaf6zQIJbfaSEAhqD5yo72+sCAwEAAQJBAK8PEVU23Wj8mV0QjwcJ +tZ4GcTUYQL7cF4+ezTCE9a1NrGnCP2RuQkHEKxuTVrxXt+6OF15/1/fuXnxKjmJC +nxkCIQDaXvPPBi0c7vAxGwNY9726x01/dNbHCE0CBtcotobxpwIhANbbQbh3JHVW +2haQh4fAG5mhesZKAGcxTyv4mQ7uMSQdAiAj+4dzMpJWdSzQ+qGHlHMIBvVHLkqB +y2VdEyF7DPCZewIhAI7GOI/6LDIFOvtPo6Bj2nNmyQ1HU6k/LRtNIXi4c9NJAiAr +rrxx26itVhJmcvoUhOjwuzSlP2bE5VHAvkGB352YBg== +-----END RSA PRIVATE KEY-----` // keychain implements the ClientPublickey interface type keychain struct { - keys []*rsa.PrivateKey + keys []interface{} } func (k *keychain) Key(i int) (interface{}, error) { if i < 0 || i >= len(k.keys) { return nil, nil } - return k.keys[i].PublicKey, nil + switch key := k.keys[i].(type) { + case *rsa.PrivateKey: + return key.PublicKey, nil + case *dsa.PrivateKey: + return key.PublicKey, nil + } + panic("unknown key type") } func (k *keychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err error) { @@ -71,7 +81,11 @@ func (k *keychain) Sign(i int, rand io.Reader, data []byte) (sig []byte, err err h := hashFunc.New() h.Write(data) digest := h.Sum(nil) - return rsa.SignPKCS1v15(rand, k.keys[i], hashFunc, digest) + switch key := k.keys[i].(type) { + case *rsa.PrivateKey: + return rsa.SignPKCS1v15(rand, key, hashFunc, digest) + } + return nil, errors.New("unknown key type") } func (k *keychain) loadPEM(file string) error { @@ -91,158 +105,153 @@ func (k *keychain) loadPEM(file string) error { return nil } -var pkey *rsa.PrivateKey +// password implements the ClientPassword interface +type password string -func init() { - var err error - pkey, err = rsa.GenerateKey(rand.Reader, 512) - if err != nil { - panic("unable to generate public key") - } +func (p password) Password(user string) (string, error) { + return string(p), nil } -func TestClientAuthPublickey(t *testing.T) { - k := new(keychain) - k.keys = append(k.keys, pkey) +// reused internally by tests +var ( + rsakey *rsa.PrivateKey + dsakey *dsa.PrivateKey + clientKeychain = new(keychain) + clientPassword = password("tiger") + serverConfig = &ServerConfig{ + PasswordCallback: func(user, pass string) bool { + return user == "testuser" && pass == string(clientPassword) + }, + PubKeyCallback: func(user, algo string, pubkey []byte) bool { + key := clientKeychain.keys[0].(*rsa.PrivateKey).PublicKey + expected := []byte(serializePublickey(key)) + algoname := algoName(key) + return user == "testuser" && algo == algoname && bytes.Equal(pubkey, expected) + }, + } +) - serverConfig.PubKeyCallback = func(user, algo string, pubkey []byte) bool { - expected := []byte(serializePublickey(k.keys[0].PublicKey)) - algoname := algoName(k.keys[0].PublicKey) - return user == "testuser" && algo == algoname && bytes.Equal(pubkey, expected) +func init() { + if err := serverConfig.SetRSAPrivateKey([]byte(testServerPrivateKey)); err != nil { + panic("unable to set private key: " + err.Error()) } - serverConfig.PasswordCallback = nil + block, _ := pem.Decode([]byte(testClientPrivateKey)) + rsakey, _ = x509.ParsePKCS1PrivateKey(block.Bytes) + + clientKeychain.keys = append(clientKeychain.keys, rsakey) + dsakey = new(dsa.PrivateKey) + // taken from crypto/dsa/dsa_test.go + dsakey.P, _ = new(big.Int).SetString("A9B5B793FB4785793D246BAE77E8FF63CA52F442DA763C440259919FE1BC1D6065A9350637A04F75A2F039401D49F08E066C4D275A5A65DA5684BC563C14289D7AB8A67163BFBF79D85972619AD2CFF55AB0EE77A9002B0EF96293BDD0F42685EBB2C66C327079F6C98000FBCB79AACDE1BC6F9D5C7B1A97E3D9D54ED7951FEF", 16) + dsakey.Q, _ = new(big.Int).SetString("E1D3391245933D68A0714ED34BBCB7A1F422B9C1", 16) + dsakey.G, _ = new(big.Int).SetString("634364FC25248933D01D1993ECABD0657CC0CB2CEED7ED2E3E8AECDFCDC4A25C3B15E9E3B163ACA2984B5539181F3EFF1A5E8903D71D5B95DA4F27202B77D2C44B430BB53741A8D59A8F86887525C9F2A6A5980A195EAA7F2FF910064301DEF89D3AA213E1FAC7768D89365318E370AF54A112EFBA9246D9158386BA1B4EEFDA", 16) + dsakey.Y, _ = new(big.Int).SetString("32969E5780CFE1C849A1C276D7AEB4F38A23B591739AA2FE197349AEEBD31366AEE5EB7E6C6DDB7C57D02432B30DB5AA66D9884299FAA72568944E4EEDC92EA3FBC6F39F53412FBCC563208F7C15B737AC8910DBC2D9C9B8C001E72FDC40EB694AB1F06A5A2DBD18D9E36C66F31F566742F11EC0A52E9F7B89355C02FB5D32D2", 16) + dsakey.X, _ = new(big.Int).SetString("5078D4D29795CBE76D3AACFE48C9AF0BCDBEE91A", 16) +} + +// newMockAuthServer creates a new Server bound to +// the loopback interface. The server exits after +// processing one handshake. +func newMockAuthServer(t *testing.T) string { l, err := Listen("tcp", "127.0.0.1:0", serverConfig) if err != nil { - t.Fatalf("unable to listen: %s", err) + t.Fatalf("unable to newMockAuthServer: %s", err) } - defer l.Close() - - done := make(chan bool, 1) go func() { + defer l.Close() c, err := l.Accept() + defer c.Close() if err != nil { - t.Fatal(err) + t.Errorf("Unable to accept incoming connection: %v", err) + return } - defer c.Close() if err := c.Handshake(); err != nil { - t.Error(err) + // not Errorf because this is expected to + // fail for some tests. + t.Logf("Handshaking error: %v", err) + return } - done <- true }() + return l.Addr().String() +} +func TestClientAuthPublickey(t *testing.T) { config := &ClientConfig{ User: "testuser", Auth: []ClientAuth{ - ClientAuthPublickey(k), + ClientAuthPublickey(clientKeychain), }, } - - c, err := Dial("tcp", l.Addr().String(), config) + c, err := Dial("tcp", newMockAuthServer(t), config) if err != nil { t.Fatalf("unable to dial remote side: %s", err) } - defer c.Close() - <-done -} - -// password implements the ClientPassword interface -type password string - -func (p password) Password(user string) (string, error) { - return string(p), nil + c.Close() } func TestClientAuthPassword(t *testing.T) { - pw := password("tiger") - - serverConfig.PasswordCallback = func(user, pass string) bool { - return user == "testuser" && pass == string(pw) + config := &ClientConfig{ + User: "testuser", + Auth: []ClientAuth{ + ClientAuthPassword(clientPassword), + }, } - serverConfig.PubKeyCallback = nil - l, err := Listen("tcp", "127.0.0.1:0", serverConfig) + c, err := Dial("tcp", newMockAuthServer(t), config) if err != nil { - t.Fatalf("unable to listen: %s", err) + t.Fatalf("unable to dial remote side: %s", err) } - defer l.Close() - - done := make(chan bool) - go func() { - c, err := l.Accept() - if err != nil { - t.Fatal(err) - } - if err := c.Handshake(); err != nil { - t.Error(err) - } - defer c.Close() - done <- true - }() + c.Close() +} +func TestClientAuthWrongPassword(t *testing.T) { + wrongPw := password("wrong") config := &ClientConfig{ User: "testuser", Auth: []ClientAuth{ - ClientAuthPassword(pw), + ClientAuthPassword(wrongPw), + ClientAuthPublickey(clientKeychain), }, } - c, err := Dial("tcp", l.Addr().String(), config) + c, err := Dial("tcp", newMockAuthServer(t), config) if err != nil { t.Fatalf("unable to dial remote side: %s", err) } - defer c.Close() - <-done + c.Close() } -func TestClientAuthPasswordAndPublickey(t *testing.T) { - pw := password("tiger") - - serverConfig.PasswordCallback = func(user, pass string) bool { - return user == "testuser" && pass == string(pw) - } - - k := new(keychain) - k.keys = append(k.keys, pkey) - - serverConfig.PubKeyCallback = func(user, algo string, pubkey []byte) bool { - expected := []byte(serializePublickey(k.keys[0].PublicKey)) - algoname := algoName(k.keys[0].PublicKey) - return user == "testuser" && algo == algoname && bytes.Equal(pubkey, expected) +// the mock server will only authenticate ssh-rsa keys +func TestClientAuthInvalidPublickey(t *testing.T) { + kc := new(keychain) + kc.keys = append(kc.keys, dsakey) + config := &ClientConfig{ + User: "testuser", + Auth: []ClientAuth{ + ClientAuthPublickey(kc), + }, } - l, err := Listen("tcp", "127.0.0.1:0", serverConfig) - if err != nil { - t.Fatalf("unable to listen: %s", err) + c, err := Dial("tcp", newMockAuthServer(t), config) + if err == nil { + c.Close() + t.Fatalf("dsa private key should not have authenticated with rsa public key") } - defer l.Close() - - done := make(chan bool) - go func() { - c, err := l.Accept() - if err != nil { - t.Fatal(err) - } - if err := c.Handshake(); err != nil { - t.Error(err) - } - defer c.Close() - done <- true - }() +} - wrongPw := password("wrong") +// the client should authenticate with the second key +func TestClientAuthRSAandDSA(t *testing.T) { + kc := new(keychain) + kc.keys = append(kc.keys, dsakey, rsakey) config := &ClientConfig{ User: "testuser", Auth: []ClientAuth{ - ClientAuthPassword(wrongPw), - ClientAuthPublickey(k), + ClientAuthPublickey(kc), }, } - - c, err := Dial("tcp", l.Addr().String(), config) + c, err := Dial("tcp", newMockAuthServer(t), config) if err != nil { - t.Fatalf("unable to dial remote side: %s", err) + t.Fatalf("client could not authenticate with rsa key: %v", err) } - defer c.Close() - <-done + c.Close() } diff --git a/libgo/go/exp/ssh/common_test.go b/libgo/go/exp/ssh/common_test.go index 2f4448a1bd4..058fb04fe1b 100644 --- a/libgo/go/exp/ssh/common_test.go +++ b/libgo/go/exp/ssh/common_test.go @@ -8,15 +8,15 @@ import ( "testing" ) -var strings = map[string]string{ - "\x20\x0d\x0a": "\x20\x0d\x0a", - "flibble": "flibble", - "new\x20line": "new\x20line", - "123456\x07789": "123456 789", - "\t\t\x10\r\n": "\t\t \r\n", -} - func TestSafeString(t *testing.T) { + strings := map[string]string{ + "\x20\x0d\x0a": "\x20\x0d\x0a", + "flibble": "flibble", + "new\x20line": "new\x20line", + "123456\x07789": "123456 789", + "\t\t\x10\r\n": "\t\t \r\n", + } + for s, expected := range strings { actual := safeString(s) if expected != actual { diff --git a/libgo/go/exp/ssh/session.go b/libgo/go/exp/ssh/session.go index 5f98a8d58c6..23ea18c29ae 100644 --- a/libgo/go/exp/ssh/session.go +++ b/libgo/go/exp/ssh/session.go @@ -285,13 +285,8 @@ func (s *Session) stdin() error { s.Stdin = new(bytes.Buffer) } s.copyFuncs = append(s.copyFuncs, func() error { - w := &chanWriter{ - packetWriter: s, - peersId: s.peersId, - win: s.win, - } - _, err := io.Copy(w, s.Stdin) - if err1 := w.Close(); err == nil { + _, err := io.Copy(s.clientChan.stdin, s.Stdin) + if err1 := s.clientChan.stdin.Close(); err == nil { err = err1 } return err @@ -304,12 +299,7 @@ func (s *Session) stdout() error { s.Stdout = ioutil.Discard } s.copyFuncs = append(s.copyFuncs, func() error { - r := &chanReader{ - packetWriter: s, - peersId: s.peersId, - data: s.data, - } - _, err := io.Copy(s.Stdout, r) + _, err := io.Copy(s.Stdout, s.clientChan.stdout) return err }) return nil @@ -320,12 +310,7 @@ func (s *Session) stderr() error { s.Stderr = ioutil.Discard } s.copyFuncs = append(s.copyFuncs, func() error { - r := &chanReader{ - packetWriter: s, - peersId: s.peersId, - data: s.dataExt, - } - _, err := io.Copy(s.Stderr, r) + _, err := io.Copy(s.Stderr, s.clientChan.stderr) return err }) return nil @@ -398,19 +383,11 @@ func (c *ClientConn) NewSession() (*Session, error) { c.chanlist.remove(ch.id) return nil, err } - // wait for response - msg := <-ch.msg - switch msg := msg.(type) { - case *channelOpenConfirmMsg: - ch.peersId = msg.MyId - ch.win <- int(msg.MyWindow) - return &Session{ - clientChan: ch, - }, nil - case *channelOpenFailureMsg: + if err := ch.waitForChannelOpenResponse(); err != nil { c.chanlist.remove(ch.id) - return nil, fmt.Errorf("ssh: channel open failed: %s", msg.Message) + return nil, fmt.Errorf("ssh: unable to open session: %v", err) } - c.chanlist.remove(ch.id) - return nil, fmt.Errorf("ssh: unexpected message %T: %v", msg, msg) + return &Session{ + clientChan: ch, + }, nil } diff --git a/libgo/go/exp/ssh/session_test.go b/libgo/go/exp/ssh/session_test.go index 4be7746d17e..d4818c29f70 100644 --- a/libgo/go/exp/ssh/session_test.go +++ b/libgo/go/exp/ssh/session_test.go @@ -61,7 +61,7 @@ func dial(t *testing.T) *ClientConn { WantReply bool Status uint32 } - // TODO(dfc) casting to the concrete type should not be + // TODO(dfc) converting to the concrete type should not be // necessary to send a packet. msg := exitMsg{ PeersId: ch.(*channel).theirId, diff --git a/libgo/go/exp/ssh/tcpip.go b/libgo/go/exp/ssh/tcpip.go index f3bbac5d19e..a85044ace9c 100644 --- a/libgo/go/exp/ssh/tcpip.go +++ b/libgo/go/exp/ssh/tcpip.go @@ -6,6 +6,7 @@ package ssh import ( "errors" + "fmt" "io" "net" ) @@ -42,20 +43,21 @@ func (c *ClientConn) DialTCP(n string, laddr, raddr *net.TCPAddr) (net.Conn, err }, nil } +// RFC 4254 7.2 +type channelOpenDirectMsg struct { + ChanType string + PeersId uint32 + PeersWindow uint32 + MaxPacketSize uint32 + raddr string + rport uint32 + laddr string + lport uint32 +} + // dial opens a direct-tcpip connection to the remote server. laddr and raddr are passed as // strings and are expected to be resolveable at the remote end. func (c *ClientConn) dial(laddr string, lport int, raddr string, rport int) (*tcpchan, error) { - // RFC 4254 7.2 - type channelOpenDirectMsg struct { - ChanType string - PeersId uint32 - PeersWindow uint32 - MaxPacketSize uint32 - raddr string - rport uint32 - laddr string - lport uint32 - } ch := c.newChan(c.transport) if err := c.writePacket(marshal(msgChannelOpen, channelOpenDirectMsg{ ChanType: "direct-tcpip", @@ -70,30 +72,14 @@ func (c *ClientConn) dial(laddr string, lport int, raddr string, rport int) (*tc c.chanlist.remove(ch.id) return nil, err } - // wait for response - switch msg := (<-ch.msg).(type) { - case *channelOpenConfirmMsg: - ch.peersId = msg.MyId - ch.win <- int(msg.MyWindow) - case *channelOpenFailureMsg: - c.chanlist.remove(ch.id) - return nil, errors.New("ssh: error opening remote TCP connection: " + msg.Message) - default: + if err := ch.waitForChannelOpenResponse(); err != nil { c.chanlist.remove(ch.id) - return nil, errors.New("ssh: unexpected packet") + return nil, fmt.Errorf("ssh: unable to open direct tcpip connection: %v", err) } return &tcpchan{ clientChan: ch, - Reader: &chanReader{ - packetWriter: ch, - peersId: ch.peersId, - data: ch.data, - }, - Writer: &chanWriter{ - packetWriter: ch, - peersId: ch.peersId, - win: ch.win, - }, + Reader: ch.stdout, + Writer: ch.stdin, }, nil } diff --git a/libgo/go/exp/types/gcimporter.go b/libgo/go/exp/types/gcimporter.go index 16a8667ff66..6adcc2a9ad2 100644 --- a/libgo/go/exp/types/gcimporter.go +++ b/libgo/go/exp/types/gcimporter.go @@ -305,7 +305,7 @@ func (p *gcParser) parseArrayType() Type { lit := p.expect(scanner.Int) p.expect(']') elt := p.parseType() - n, err := strconv.Atoui64(lit) + n, err := strconv.ParseUint(lit, 10, 64) if err != nil { p.error(err) } @@ -323,7 +323,7 @@ func (p *gcParser) parseMapType() Type { return &Map{Key: key, Elt: elt} } -// Name = identifier | "?" . +// Name = identifier | "?" | ExportedName . // func (p *gcParser) parseName() (name string) { switch p.tok { @@ -333,6 +333,9 @@ func (p *gcParser) parseName() (name string) { case '?': // anonymous p.next() + case '@': + // exported name prefixed with package path + _, name = p.parseExportedName() default: p.error("name expected") } @@ -619,10 +622,11 @@ func (p *gcParser) parseNumber() Const { // exponent (base 2) p.next() sign, val = p.parseInt() - exp, err := strconv.Atoui(val) + exp64, err := strconv.ParseUint(val, 10, 0) if err != nil { p.error(err) } + exp := uint(exp64) if sign == "-" { denom := big.NewInt(1) denom.Lsh(denom, exp) @@ -747,7 +751,7 @@ func (p *gcParser) parseFuncDecl() { } } -// MethodDecl = "func" Receiver identifier Signature . +// MethodDecl = "func" Receiver Name Signature . // Receiver = "(" ( identifier | "?" ) [ "*" ] ExportedName ")" [ FuncBody ]. // func (p *gcParser) parseMethodDecl() { @@ -755,7 +759,7 @@ func (p *gcParser) parseMethodDecl() { p.expect('(') p.parseParameter() // receiver p.expect(')') - p.expect(scanner.Ident) + p.parseName() // unexported method names in imports are qualified with their package. p.parseSignature() if p.tok == '{' { p.parseFuncBody() diff --git a/libgo/go/expvar/expvar.go b/libgo/go/expvar/expvar.go index 629280acf76..40f5441ddcb 100644 --- a/libgo/go/expvar/expvar.go +++ b/libgo/go/expvar/expvar.go @@ -44,7 +44,7 @@ type Int struct { mu sync.Mutex } -func (v *Int) String() string { return strconv.Itoa64(v.i) } +func (v *Int) String() string { return strconv.FormatInt(v.i, 10) } func (v *Int) Add(delta int64) { v.mu.Lock() @@ -64,7 +64,7 @@ type Float struct { mu sync.Mutex } -func (v *Float) String() string { return strconv.Ftoa64(v.f, 'g', -1) } +func (v *Float) String() string { return strconv.FormatFloat(v.f, 'g', -1, 64) } // Add adds delta to v. func (v *Float) Add(delta float64) { diff --git a/libgo/go/flag/flag.go b/libgo/go/flag/flag.go index 9f115d592bd..406ea77799d 100644 --- a/libgo/go/flag/flag.go +++ b/libgo/go/flag/flag.go @@ -79,7 +79,7 @@ func newBoolValue(val bool, p *bool) *boolValue { } func (b *boolValue) Set(s string) bool { - v, err := strconv.Atob(s) + v, err := strconv.ParseBool(s) *b = boolValue(v) return err == nil } @@ -95,7 +95,7 @@ func newIntValue(val int, p *int) *intValue { } func (i *intValue) Set(s string) bool { - v, err := strconv.Btoi64(s, 0) + v, err := strconv.ParseInt(s, 0, 64) *i = intValue(v) return err == nil } @@ -111,7 +111,7 @@ func newInt64Value(val int64, p *int64) *int64Value { } func (i *int64Value) Set(s string) bool { - v, err := strconv.Btoi64(s, 0) + v, err := strconv.ParseInt(s, 0, 64) *i = int64Value(v) return err == nil } @@ -127,7 +127,7 @@ func newUintValue(val uint, p *uint) *uintValue { } func (i *uintValue) Set(s string) bool { - v, err := strconv.Btoui64(s, 0) + v, err := strconv.ParseUint(s, 0, 64) *i = uintValue(v) return err == nil } @@ -143,7 +143,7 @@ func newUint64Value(val uint64, p *uint64) *uint64Value { } func (i *uint64Value) Set(s string) bool { - v, err := strconv.Btoui64(s, 0) + v, err := strconv.ParseUint(s, 0, 64) *i = uint64Value(v) return err == nil } @@ -174,7 +174,7 @@ func newFloat64Value(val float64, p *float64) *float64Value { } func (f *float64Value) Set(s string) bool { - v, err := strconv.Atof64(s) + v, err := strconv.ParseFloat(s, 64) *f = float64Value(v) return err == nil } diff --git a/libgo/go/fmt/doc.go b/libgo/go/fmt/doc.go index 6713f0a16ed..11e9f19f899 100644 --- a/libgo/go/fmt/doc.go +++ b/libgo/go/fmt/doc.go @@ -89,18 +89,22 @@ If an operand implements interface Formatter, that interface can be used for fine control of formatting. - Next, if an operand implements the error interface, the Error method + If the format (which is implicitly %v for Println etc.) is valid + for a string (%s %q %v %x %X), the following two rules also apply: + + 1. If an operand implements the error interface, the Error method will be used to convert the object to a string, which will then be formatted as required by the verb (if any). - Finally, if an operand implements method String() string that method + 2. If an operand implements method String() string, that method will be used to convert the object to a string, which will then be formatted as required by the verb (if any). + To avoid recursion in cases such as - type X int - func (x X) String() string { return Sprintf("%d", x) } - cast the value before recurring: - func (x X) String() string { return Sprintf("%d", int(x)) } + type X string + func (x X) String() string { return Sprintf("<%s>", x) } + convert the value before recurring: + func (x X) String() string { return Sprintf("<%s>", string(x)) } Format errors: diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go index 00aac798cb0..63c33380a25 100644 --- a/libgo/go/fmt/fmt_test.go +++ b/libgo/go/fmt/fmt_test.go @@ -12,6 +12,7 @@ import ( "runtime" // for the malloc count test only "strings" "testing" + "time" ) type ( @@ -352,7 +353,7 @@ var fmttests = []struct { {"%s", I(23), `<23>`}, {"%q", I(23), `"<23>"`}, {"%x", I(23), `3c32333e`}, - {"%d", I(23), `%!d(string=<23>)`}, + {"%d", I(23), `23`}, // Stringer applies only to string formats. // go syntax {"%#v", A{1, 2, "a", []int{1, 2}}, `fmt_test.A{i:1, j:0x2, s:"a", x:[]int{1, 2}}`}, @@ -361,8 +362,8 @@ var fmttests = []struct { {"%#v", make(chan int), "(chan int)(0xPTR)"}, {"%#v", uint64(1<<64 - 1), "0xffffffffffffffff"}, {"%#v", 1000000000, "1000000000"}, - {"%#v", map[string]int{"a": 1}, `map[string] int{"a":1}`}, - {"%#v", map[string]B{"a": {1, 2}}, `map[string] fmt_test.B{"a":fmt_test.B{I:1, j:2}}`}, + {"%#v", map[string]int{"a": 1}, `map[string]int{"a":1}`}, + {"%#v", map[string]B{"a": {1, 2}}, `map[string]fmt_test.B{"a":fmt_test.B{I:1, j:2}}`}, {"%#v", []string{"a", "b"}, `[]string{"a", "b"}`}, {"%#v", SI{}, `fmt_test.SI{I:interface {}(nil)}`}, {"%#v", []int(nil), `[]int(nil)`}, @@ -371,8 +372,8 @@ var fmttests = []struct { {"%#v", &array, `&[5]int{1, 2, 3, 4, 5}`}, {"%#v", iarray, `[4]interface {}{1, "hello", 2.5, interface {}(nil)}`}, {"%#v", &iarray, `&[4]interface {}{1, "hello", 2.5, interface {}(nil)}`}, - {"%#v", map[int]byte(nil), `map[int] uint8(nil)`}, - {"%#v", map[int]byte{}, `map[int] uint8{}`}, + {"%#v", map[int]byte(nil), `map[int]uint8(nil)`}, + {"%#v", map[int]byte{}, `map[int]uint8{}`}, // slices with other formats {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`}, @@ -430,6 +431,10 @@ var fmttests = []struct { {"%p", make([]int, 1), "0xPTR"}, {"%p", 27, "%!p(int=27)"}, // not a pointer at all + // %d on Stringer should give integer if possible + {"%s", time.Time{}.Month(), "January"}, + {"%d", time.Time{}.Month(), "1"}, + // erroneous things {"%s %", "hello", "hello %!(NOVERB)"}, {"%s %.2", "hello", "hello %!(NOVERB)"}, @@ -495,69 +500,84 @@ func BenchmarkSprintfPrefixedInt(b *testing.B) { } } +func BenchmarkSprintfFloat(b *testing.B) { + for i := 0; i < b.N; i++ { + Sprintf("%g", 5.23184) + } +} + func TestCountMallocs(t *testing.T) { if testing.Short() { return } + const N = 100 runtime.UpdateMemStats() mallocs := 0 - runtime.MemStats.Mallocs - for i := 0; i < 100; i++ { + for i := 0; i < N; i++ { Sprintf("") } runtime.UpdateMemStats() mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"\"): %d\n", mallocs/100) + Printf("mallocs per Sprintf(\"\"): %d\n", mallocs/N) runtime.UpdateMemStats() mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < 100; i++ { + for i := 0; i < N; i++ { Sprintf("xxx") } runtime.UpdateMemStats() mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"xxx\"): %d\n", mallocs/100) + Printf("mallocs per Sprintf(\"xxx\"): %d\n", mallocs/N) runtime.UpdateMemStats() mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < 100; i++ { + for i := 0; i < N; i++ { Sprintf("%x", i) } runtime.UpdateMemStats() mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"%%x\"): %d\n", mallocs/100) + Printf("mallocs per Sprintf(\"%%x\"): %d\n", mallocs/N) runtime.UpdateMemStats() mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < 100; i++ { + for i := 0; i < N; i++ { Sprintf("%s", "hello") } runtime.UpdateMemStats() mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"%%s\"): %d\n", mallocs/100) + Printf("mallocs per Sprintf(\"%%s\"): %d\n", mallocs/N) runtime.UpdateMemStats() mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < 100; i++ { + for i := 0; i < N; i++ { Sprintf("%x %x", i, i) } runtime.UpdateMemStats() mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Sprintf(\"%%x %%x\"): %d\n", mallocs/100) + Printf("mallocs per Sprintf(\"%%x %%x\"): %d\n", mallocs/N) + runtime.UpdateMemStats() + mallocs = 0 - runtime.MemStats.Mallocs + for i := 0; i < N; i++ { + Sprintf("%g", 3.14159) + } + runtime.UpdateMemStats() + mallocs += runtime.MemStats.Mallocs + Printf("mallocs per Sprintf(\"%%g\"): %d\n", mallocs/N) buf := new(bytes.Buffer) runtime.UpdateMemStats() mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < 100; i++ { + for i := 0; i < N; i++ { buf.Reset() Fprintf(buf, "%x %x %x", i, i, i) } runtime.UpdateMemStats() mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Fprintf(buf, \"%%x %%x %%x\"): %d\n", mallocs/100) + Printf("mallocs per Fprintf(buf, \"%%x %%x %%x\"): %d\n", mallocs/N) runtime.UpdateMemStats() mallocs = 0 - runtime.MemStats.Mallocs - for i := 0; i < 100; i++ { + for i := 0; i < N; i++ { buf.Reset() Fprintf(buf, "%s", "hello") } runtime.UpdateMemStats() mallocs += runtime.MemStats.Mallocs - Printf("mallocs per Fprintf(buf, \"%%s\"): %d\n", mallocs/100) + Printf("mallocs per Fprintf(buf, \"%%s\"): %d\n", mallocs/N) } type flagPrinter struct{} @@ -772,9 +792,9 @@ var panictests = []struct { out string }{ // String - {"%d", (*Panic)(nil), "<nil>"}, // nil pointer special case - {"%d", Panic{io.ErrUnexpectedEOF}, "%d(PANIC=unexpected EOF)"}, - {"%d", Panic{3}, "%d(PANIC=3)"}, + {"%s", (*Panic)(nil), "<nil>"}, // nil pointer special case + {"%s", Panic{io.ErrUnexpectedEOF}, "%s(PANIC=unexpected EOF)"}, + {"%s", Panic{3}, "%s(PANIC=3)"}, // GoString {"%#v", (*Panic)(nil), "<nil>"}, // nil pointer special case {"%#v", Panic{io.ErrUnexpectedEOF}, "%v(PANIC=unexpected EOF)"}, diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go index 3957a5a261d..fbafa9d9ad9 100644 --- a/libgo/go/fmt/format.go +++ b/libgo/go/fmt/format.go @@ -360,44 +360,44 @@ func (f *fmt) plusSpace(s string) { } // fmt_e64 formats a float64 in the form -1.23e+12. -func (f *fmt) fmt_e64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'e', doPrec(f, 6))) } +func (f *fmt) fmt_e64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'e', doPrec(f, 6), 64)) } // fmt_E64 formats a float64 in the form -1.23E+12. -func (f *fmt) fmt_E64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'E', doPrec(f, 6))) } +func (f *fmt) fmt_E64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'E', doPrec(f, 6), 64)) } // fmt_f64 formats a float64 in the form -1.23. -func (f *fmt) fmt_f64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'f', doPrec(f, 6))) } +func (f *fmt) fmt_f64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'f', doPrec(f, 6), 64)) } // fmt_g64 formats a float64 in the 'f' or 'e' form according to size. -func (f *fmt) fmt_g64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'g', doPrec(f, -1))) } +func (f *fmt) fmt_g64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'g', doPrec(f, -1), 64)) } // fmt_g64 formats a float64 in the 'f' or 'E' form according to size. -func (f *fmt) fmt_G64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'G', doPrec(f, -1))) } +func (f *fmt) fmt_G64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'G', doPrec(f, -1), 64)) } // fmt_fb64 formats a float64 in the form -123p3 (exponent is power of 2). -func (f *fmt) fmt_fb64(v float64) { f.plusSpace(strconv.Ftoa64(v, 'b', 0)) } +func (f *fmt) fmt_fb64(v float64) { f.plusSpace(strconv.FormatFloat(v, 'b', 0, 64)) } // float32 // cannot defer to float64 versions // because it will get rounding wrong in corner cases. // fmt_e32 formats a float32 in the form -1.23e+12. -func (f *fmt) fmt_e32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'e', doPrec(f, 6))) } +func (f *fmt) fmt_e32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'e', doPrec(f, 6), 32)) } // fmt_E32 formats a float32 in the form -1.23E+12. -func (f *fmt) fmt_E32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'E', doPrec(f, 6))) } +func (f *fmt) fmt_E32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'E', doPrec(f, 6), 32)) } // fmt_f32 formats a float32 in the form -1.23. -func (f *fmt) fmt_f32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'f', doPrec(f, 6))) } +func (f *fmt) fmt_f32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'f', doPrec(f, 6), 32)) } // fmt_g32 formats a float32 in the 'f' or 'e' form according to size. -func (f *fmt) fmt_g32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'g', doPrec(f, -1))) } +func (f *fmt) fmt_g32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'g', doPrec(f, -1), 32)) } // fmt_G32 formats a float32 in the 'f' or 'E' form according to size. -func (f *fmt) fmt_G32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'G', doPrec(f, -1))) } +func (f *fmt) fmt_G32(v float32) { f.plusSpace(strconv.FormatFloat(float64(v), 'G', doPrec(f, -1), 32)) } // fmt_fb32 formats a float32 in the form -123p3 (exponent is power of 2). -func (f *fmt) fmt_fb32(v float32) { f.padString(strconv.Ftoa32(v, 'b', 0)) } +func (f *fmt) fmt_fb32(v float32) { f.padString(strconv.FormatFloat(float64(v), 'b', 0, 32)) } // fmt_c64 formats a complex64 according to the verb. func (f *fmt) fmt_c64(v complex64, verb rune) { diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go index e5ca1172405..8b15a82e773 100644 --- a/libgo/go/fmt/print.go +++ b/libgo/go/fmt/print.go @@ -631,24 +631,30 @@ func (p *pp) handleMethods(verb rune, plus, goSyntax bool, depth int) (wasString return } } else { - // Is it an error or Stringer? - // The duplication in the bodies is necessary: - // setting wasString and handled and deferring catchPanic - // must happen before calling the method. - switch v := p.field.(type) { - case error: - wasString = false - handled = true - defer p.catchPanic(p.field, verb) - p.printField(v.Error(), verb, plus, false, depth) - return - - case Stringer: - wasString = false - handled = true - defer p.catchPanic(p.field, verb) - p.printField(v.String(), verb, plus, false, depth) - return + // If a string is acceptable according to the format, see if + // the value satisfies one of the string-valued interfaces. + // Println etc. set verb to %v, which is "stringable". + switch verb { + case 'v', 's', 'x', 'X', 'q': + // Is it an error or Stringer? + // The duplication in the bodies is necessary: + // setting wasString and handled, and deferring catchPanic, + // must happen before calling the method. + switch v := p.field.(type) { + case error: + wasString = false + handled = true + defer p.catchPanic(p.field, verb) + p.printField(v.Error(), verb, plus, false, depth) + return + + case Stringer: + wasString = false + handled = true + defer p.catchPanic(p.field, verb) + p.printField(v.String(), verb, plus, false, depth) + return + } } } handled = false diff --git a/libgo/go/fmt/scan.go b/libgo/go/fmt/scan.go index 85571e80c7a..281525112e1 100644 --- a/libgo/go/fmt/scan.go +++ b/libgo/go/fmt/scan.go @@ -613,7 +613,7 @@ func (s *ss) scanInt(verb rune, bitSize int) int64 { } } tok := s.scanNumber(digits, haveDigits) - i, err := strconv.Btoi64(tok, base) + i, err := strconv.ParseInt(tok, base, 64) if err != nil { s.error(err) } @@ -643,7 +643,7 @@ func (s *ss) scanUint(verb rune, bitSize int) uint64 { base, digits, haveDigits = s.scanBasePrefix() } tok := s.scanNumber(digits, haveDigits) - i, err := strconv.Btoui64(tok, base) + i, err := strconv.ParseUint(tok, base, 64) if err != nil { s.error(err) } @@ -719,7 +719,7 @@ func (s *ss) convertFloat(str string, n int) float64 { if p := strings.Index(str, "p"); p >= 0 { // Atof doesn't handle power-of-2 exponents, // but they're easy to evaluate. - f, err := strconv.AtofN(str[:p], n) + f, err := strconv.ParseFloat(str[:p], n) if err != nil { // Put full string into error. if e, ok := err.(*strconv.NumError); ok { @@ -737,7 +737,7 @@ func (s *ss) convertFloat(str string, n int) float64 { } return math.Ldexp(f, n) } - f, err := strconv.AtofN(str, n) + f, err := strconv.ParseFloat(str, n) if err != nil { s.error(err) } diff --git a/libgo/go/go/ast/print_test.go b/libgo/go/go/ast/print_test.go index c3153ed6f72..89d5af1541e 100644 --- a/libgo/go/go/ast/print_test.go +++ b/libgo/go/go/ast/print_test.go @@ -24,7 +24,7 @@ var tests = []struct { // maps {map[string]int{"a": 1}, - `0 map[string] int (len = 1) { + `0 map[string]int (len = 1) { 1 . "a": 1 2 }`}, diff --git a/libgo/go/go/doc/comment.go b/libgo/go/go/doc/comment.go index d7bb384ed03..c9fb55bd54e 100644 --- a/libgo/go/go/doc/comment.go +++ b/libgo/go/go/doc/comment.go @@ -7,7 +7,6 @@ package doc import ( - "bytes" "go/ast" "io" "regexp" @@ -85,39 +84,6 @@ func CommentText(comment *ast.CommentGroup) string { return strings.Join(lines, "\n") } -// Split bytes into lines. -func split(text []byte) [][]byte { - // count lines - n := 0 - last := 0 - for i, c := range text { - if c == '\n' { - last = i + 1 - n++ - } - } - if last < len(text) { - n++ - } - - // split - out := make([][]byte, n) - last = 0 - n = 0 - for i, c := range text { - if c == '\n' { - out[n] = text[last : i+1] - last = i + 1 - n++ - } - } - if last < len(text) { - out[n] = text[last:] - } - - return out -} - var ( ldquo = []byte("“") rdquo = []byte("”") @@ -125,13 +91,13 @@ var ( // Escape comment text for HTML. If nice is set, // also turn `` into “ and '' into ”. -func commentEscape(w io.Writer, s []byte, nice bool) { +func commentEscape(w io.Writer, text string, nice bool) { last := 0 if nice { - for i := 0; i < len(s)-1; i++ { - ch := s[i] - if ch == s[i+1] && (ch == '`' || ch == '\'') { - template.HTMLEscape(w, s[last:i]) + for i := 0; i < len(text)-1; i++ { + ch := text[i] + if ch == text[i+1] && (ch == '`' || ch == '\'') { + template.HTMLEscape(w, []byte(text[last:i])) last = i + 2 switch ch { case '`': @@ -143,7 +109,7 @@ func commentEscape(w io.Writer, s []byte, nice bool) { } } } - template.HTMLEscape(w, s[last:]) + template.HTMLEscape(w, []byte(text[last:])) } const ( @@ -183,9 +149,9 @@ var ( // and the word is converted into a link. If nice is set, the remaining text's // appearance is improved where it makes sense (e.g., `` is turned into “ // and '' into ”). -func emphasize(w io.Writer, line []byte, words map[string]string, nice bool) { +func emphasize(w io.Writer, line string, words map[string]string, nice bool) { for { - m := matchRx.FindSubmatchIndex(line) + m := matchRx.FindStringSubmatchIndex(line) if m == nil { break } @@ -233,7 +199,7 @@ func emphasize(w io.Writer, line []byte, words map[string]string, nice bool) { commentEscape(w, line, nice) } -func indentLen(s []byte) int { +func indentLen(s string) int { i := 0 for i < len(s) && (s[i] == ' ' || s[i] == '\t') { i++ @@ -241,9 +207,11 @@ func indentLen(s []byte) int { return i } -func isBlank(s []byte) bool { return len(s) == 0 || (len(s) == 1 && s[0] == '\n') } +func isBlank(s string) bool { + return len(s) == 0 || (len(s) == 1 && s[0] == '\n') +} -func commonPrefix(a, b []byte) []byte { +func commonPrefix(a, b string) string { i := 0 for i < len(a) && i < len(b) && a[i] == b[i] { i++ @@ -251,7 +219,7 @@ func commonPrefix(a, b []byte) []byte { return a[0:i] } -func unindent(block [][]byte) { +func unindent(block []string) { if len(block) == 0 { return } @@ -273,44 +241,39 @@ func unindent(block [][]byte) { } } -// heading returns the (possibly trimmed) line if it passes as a valid section -// heading; otherwise it returns nil. -func heading(line []byte) []byte { - line = bytes.TrimSpace(line) +// heading returns the trimmed line if it passes as a section heading; +// otherwise it returns the empty string. +func heading(line string) string { + line = strings.TrimSpace(line) if len(line) == 0 { - return nil + return "" } // a heading must start with an uppercase letter - r, _ := utf8.DecodeRune(line) + r, _ := utf8.DecodeRuneInString(line) if !unicode.IsLetter(r) || !unicode.IsUpper(r) { - return nil - } - - // it must end in a letter, digit or ':' - r, _ = utf8.DecodeLastRune(line) - if !unicode.IsLetter(r) && !unicode.IsDigit(r) && r != ':' { - return nil + return "" } - // strip trailing ':', if any - if r == ':' { - line = line[0 : len(line)-1] + // it must end in a letter or digit: + r, _ = utf8.DecodeLastRuneInString(line) + if !unicode.IsLetter(r) && !unicode.IsDigit(r) { + return "" } // exclude lines with illegal characters - if bytes.IndexAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") >= 0 { - return nil + if strings.IndexAny(line, ",.;:!?+*/=()[]{}_^°&§~%#@<\">\\") >= 0 { + return "" } // allow "'" for possessive "'s" only for b := line; ; { - i := bytes.IndexRune(b, '\'') + i := strings.IndexRune(b, '\'') if i < 0 { break } if i+1 >= len(b) || b[i+1] != 's' || (i+2 < len(b) && b[i+2] != ' ') { - return nil // not followed by "s " + return "" // not followed by "s " } b = b[i+2:] } @@ -335,7 +298,7 @@ func heading(line []byte) []byte { // Go identifiers that appear in the words map are italicized; if the corresponding // map value is not the empty string, it is considered a URL and the word is converted // into a link. -func ToHTML(w io.Writer, s []byte, words map[string]string) { +func ToHTML(w io.Writer, text string, words map[string]string) { inpara := false lastWasBlank := false lastWasHeading := false @@ -353,7 +316,7 @@ func ToHTML(w io.Writer, s []byte, words map[string]string) { } } - lines := split(s) + lines := strings.SplitAfter(text, "\n") unindent(lines) for i := 0; i < len(lines); { line := lines[i] @@ -397,10 +360,10 @@ func ToHTML(w io.Writer, s []byte, words map[string]string) { // current line is non-blank, sourounded by blank lines // and the next non-blank line is not indented: this // might be a heading. - if head := heading(line); head != nil { + if head := heading(line); head != "" { close() w.Write(html_h) - template.HTMLEscape(w, head) + commentEscape(w, head, true) // nice text formatting w.Write(html_endh) i += 2 lastWasHeading = true diff --git a/libgo/go/go/doc/comment_test.go b/libgo/go/go/doc/comment_test.go index 870660ad628..6424053ac9d 100644 --- a/libgo/go/go/doc/comment_test.go +++ b/libgo/go/go/doc/comment_test.go @@ -18,7 +18,8 @@ var headingTests = []struct { {"Foo 42", true}, {"", false}, {"section", false}, - {"A typical usage:", true}, + {"A typical usage:", false}, + {"This code:", false}, {"δ is Greek", false}, {"Foo §", false}, {"Fermat's Last Sentence", true}, @@ -26,13 +27,13 @@ var headingTests = []struct { {"'sX", false}, {"Ted 'Too' Bar", false}, {"Use n+m", false}, - {"Scanning:", true}, + {"Scanning:", false}, {"N:M", false}, } func TestIsHeading(t *testing.T) { for _, tt := range headingTests { - if h := heading([]byte(tt.line)); (h != nil) != tt.ok { + if h := heading(tt.line); (len(h) > 0) != tt.ok { t.Errorf("isHeading(%q) = %v, want %v", tt.line, h, tt.ok) } } diff --git a/libgo/go/go/doc/headscan.go b/libgo/go/go/doc/headscan.go index 83f24627c95..838223be745 100644 --- a/libgo/go/go/doc/headscan.go +++ b/libgo/go/go/doc/headscan.go @@ -43,7 +43,7 @@ func isGoFile(fi os.FileInfo) bool { func appendHeadings(list []string, comment string) []string { var buf bytes.Buffer - doc.ToHTML(&buf, []byte(comment), nil) + doc.ToHTML(&buf, comment, nil) for s := buf.String(); ; { i := strings.Index(s, html_h) if i < 0 { diff --git a/libgo/go/go/parser/parser.go b/libgo/go/go/parser/parser.go index 55b8998b7d5..f0a8055f4c1 100644 --- a/libgo/go/go/parser/parser.go +++ b/libgo/go/go/parser/parser.go @@ -2026,7 +2026,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList { // must have exactly one receiver if par.NumFields() != 1 { p.errorExpected(par.Opening, "exactly one receiver") - par.List = []*ast.Field{&ast.Field{Type: &ast.BadExpr{par.Opening, par.Closing + 1}}} + par.List = []*ast.Field{{Type: &ast.BadExpr{par.Opening, par.Closing + 1}}} return par } @@ -2035,7 +2035,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList { base := deref(recv.Type) if _, isIdent := base.(*ast.Ident); !isIdent { p.errorExpected(base.Pos(), "(unqualified) identifier") - par.List = []*ast.Field{&ast.Field{Type: &ast.BadExpr{recv.Pos(), recv.End()}}} + par.List = []*ast.Field{{Type: &ast.BadExpr{recv.Pos(), recv.End()}}} } return par diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go index 53f36092fda..b2a48c28a73 100644 --- a/libgo/go/go/printer/nodes.go +++ b/libgo/go/go/printer/nodes.go @@ -354,7 +354,7 @@ func (p *printer) isOneLineFieldList(list []*ast.Field) bool { } func (p *printer) setLineComment(text string) { - p.setComment(&ast.CommentGroup{[]*ast.Comment{&ast.Comment{token.NoPos, text}}}) + p.setComment(&ast.CommentGroup{[]*ast.Comment{{token.NoPos, text}}}) } func (p *printer) fieldList(fields *ast.FieldList, isStruct, isIncomplete bool) { diff --git a/libgo/go/go/printer/testdata/parser.go b/libgo/go/go/printer/testdata/parser.go index 2d27af49920..89e341c5f97 100644 --- a/libgo/go/go/printer/testdata/parser.go +++ b/libgo/go/go/printer/testdata/parser.go @@ -1999,7 +1999,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList { if par.NumFields() != 1 { p.errorExpected(pos, "exactly one receiver") // TODO determine a better range for BadExpr below - par.List = []*ast.Field{&ast.Field{Type: &ast.BadExpr{pos, pos}}} + par.List = []*ast.Field{{Type: &ast.BadExpr{pos, pos}}} return par } @@ -2008,7 +2008,7 @@ func (p *parser) parseReceiver(scope *ast.Scope) *ast.FieldList { base := deref(recv.Type) if _, isIdent := base.(*ast.Ident); !isIdent { p.errorExpected(base.Pos(), "(unqualified) identifier") - par.List = []*ast.Field{&ast.Field{Type: &ast.BadExpr{recv.Pos(), recv.End()}}} + par.List = []*ast.Field{{Type: &ast.BadExpr{recv.Pos(), recv.End()}}} } return par diff --git a/libgo/go/hash/hash.go b/libgo/go/hash/hash.go index 0d7765dc505..8598f4e1b83 100644 --- a/libgo/go/hash/hash.go +++ b/libgo/go/hash/hash.go @@ -13,9 +13,9 @@ type Hash interface { // It never returns an error. io.Writer - // Sum appends the current hash in the same manner as append(), without - // changing the underlying hash state. - Sum(in []byte) []byte + // Sum appends the current hash to b and returns the resulting slice. + // It does not change the underlying hash state. + Sum(b []byte) []byte // Reset resets the hash to one with zero bytes written. Reset() diff --git a/libgo/go/html/parse.go b/libgo/go/html/parse.go index 97fbc514d82..dd2d8165bdb 100644 --- a/libgo/go/html/parse.go +++ b/libgo/go/html/parse.go @@ -515,7 +515,19 @@ func afterHeadIM(p *parser) bool { implied bool ) switch p.tok.Type { - case ErrorToken, TextToken: + case ErrorToken: + implied = true + framesetOK = true + case TextToken: + s := strings.TrimLeft(p.tok.Data, whitespace) + if len(s) < len(p.tok.Data) { + // Add the initial whitespace to the current node. + p.addText(p.tok.Data[:len(p.tok.Data)-len(s)]) + if s == "" { + return true + } + p.tok.Data = s + } implied = true framesetOK = true case StartTagToken: @@ -535,7 +547,8 @@ func afterHeadIM(p *parser) bool { defer p.oe.pop() return inHeadIM(p) case "head": - // TODO. + // Ignore the token. + return true default: implied = true framesetOK = true diff --git a/libgo/go/html/parse_test.go b/libgo/go/html/parse_test.go index e0c19cff6da..5062a6edcb8 100644 --- a/libgo/go/html/parse_test.go +++ b/libgo/go/html/parse_test.go @@ -167,6 +167,7 @@ func TestParser(t *testing.T) { {"tests3.dat", -1}, {"tests4.dat", -1}, {"tests5.dat", -1}, + {"tests6.dat", 7}, } for _, tf := range testFiles { f, err := os.Open("testdata/webkit/" + tf.filename) diff --git a/libgo/go/html/render_test.go b/libgo/go/html/render_test.go index d166a3b8736..0584f35abdb 100644 --- a/libgo/go/html/render_test.go +++ b/libgo/go/html/render_test.go @@ -14,63 +14,63 @@ func TestRenderer(t *testing.T) { Type: ElementNode, Data: "html", Child: []*Node{ - &Node{ + { Type: ElementNode, Data: "head", }, - &Node{ + { Type: ElementNode, Data: "body", Child: []*Node{ - &Node{ + { Type: TextNode, Data: "0<1", }, - &Node{ + { Type: ElementNode, Data: "p", Attr: []Attribute{ - Attribute{ + { Key: "id", Val: "A", }, - Attribute{ + { Key: "foo", Val: `abc"def`, }, }, Child: []*Node{ - &Node{ + { Type: TextNode, Data: "2", }, - &Node{ + { Type: ElementNode, Data: "b", Attr: []Attribute{ - Attribute{ + { Key: "empty", Val: "", }, }, Child: []*Node{ - &Node{ + { Type: TextNode, Data: "3", }, }, }, - &Node{ + { Type: ElementNode, Data: "i", Attr: []Attribute{ - Attribute{ + { Key: "backslash", Val: `\`, }, }, Child: []*Node{ - &Node{ + { Type: TextNode, Data: "&4", }, @@ -78,19 +78,19 @@ func TestRenderer(t *testing.T) { }, }, }, - &Node{ + { Type: TextNode, Data: "5", }, - &Node{ + { Type: ElementNode, Data: "blockquote", }, - &Node{ + { Type: ElementNode, Data: "br", }, - &Node{ + { Type: TextNode, Data: "6", }, diff --git a/libgo/go/html/template/css_test.go b/libgo/go/html/template/css_test.go index 0d94bdcf18c..a735638b031 100644 --- a/libgo/go/html/template/css_test.go +++ b/libgo/go/html/template/css_test.go @@ -113,7 +113,7 @@ func TestDecodeCSS(t *testing.T) { func TestHexDecode(t *testing.T) { for i := 0; i < 0x200000; i += 101 /* coprime with 16 */ { - s := strconv.Itob(i, 16) + s := strconv.FormatInt(int64(i), 16) if got := int(hexDecode([]byte(s))); got != i { t.Errorf("%s: want %d but got %d", s, i, got) } diff --git a/libgo/go/html/template/escape.go b/libgo/go/html/template/escape.go index 4a7a9354c93..2f6be3b6c21 100644 --- a/libgo/go/html/template/escape.go +++ b/libgo/go/html/template/escape.go @@ -716,7 +716,7 @@ func (e *escaper) editTextNode(n *parse.TextNode, text []byte) { // commit applies changes to actions and template calls needed to contextually // autoescape content and adds any derived templates to the set. func (e *escaper) commit() { - for name, _ := range e.output { + for name := range e.output { e.template(name).Funcs(funcMap) } for _, t := range e.derived { diff --git a/libgo/go/html/template/escape_test.go b/libgo/go/html/template/escape_test.go index b4daca7d6bd..cdeed48b822 100644 --- a/libgo/go/html/template/escape_test.go +++ b/libgo/go/html/template/escape_test.go @@ -689,11 +689,11 @@ func TestEscapeSet(t *testing.T) { data := dataItem{ Children: []*dataItem{ - &dataItem{X: "foo"}, - &dataItem{X: "<bar>"}, - &dataItem{ + {X: "foo"}, + {X: "<bar>"}, + { Children: []*dataItem{ - &dataItem{X: "baz"}, + {X: "baz"}, }, }, }, @@ -1597,7 +1597,7 @@ func TestRedundantFuncs(t *testing.T) { for n0, m := range redundantFuncs { f0 := funcMap[n0].(func(...interface{}) string) - for n1, _ := range m { + for n1 := range m { f1 := funcMap[n1].(func(...interface{}) string) for _, input := range inputs { want := f0(input) diff --git a/libgo/go/html/template/template.go b/libgo/go/html/template/template.go index f05ca190f73..fa2ed18874c 100644 --- a/libgo/go/html/template/template.go +++ b/libgo/go/html/template/template.go @@ -47,23 +47,22 @@ func (t *Template) Execute(wr io.Writer, data interface{}) (err error) { return t.text.Execute(wr, data) } -// ExecuteTemplate applies the template associated with t that has the given name -// to the specified data object and writes the output to wr. +// ExecuteTemplate applies the template associated with t that has the given +// name to the specified data object and writes the output to wr. func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) (err error) { t.nameSpace.mu.Lock() tmpl := t.set[name] - if tmpl == nil { - t.nameSpace.mu.Unlock() - return fmt.Errorf("template: no template %q associated with template %q", name, t.Name()) + if (tmpl == nil) != (t.text.Lookup(name) == nil) { + panic("html/template internal error: template escaping out of sync") } - if !tmpl.escaped { + if tmpl != nil && !tmpl.escaped { err = escapeTemplates(tmpl, name) } t.nameSpace.mu.Unlock() if err != nil { return } - return tmpl.text.ExecuteTemplate(wr, name, data) + return t.text.ExecuteTemplate(wr, name, data) } // Parse parses a string into a template. Nested template definitions @@ -106,7 +105,7 @@ func (t *Template) AddParseTree(name string, tree *parse.Tree) error { // Clone is unimplemented. func (t *Template) Clone(name string) error { - return fmt.Errorf("html/template: Add unimplemented") + return fmt.Errorf("html/template: Clone unimplemented") } // New allocates a new HTML template with the given name. diff --git a/libgo/go/image/color/color.go b/libgo/go/image/color/color.go index 4a0fae5a789..2948db7f38c 100644 --- a/libgo/go/image/color/color.go +++ b/libgo/go/image/color/color.go @@ -134,13 +134,22 @@ type Model interface { Convert(c Color) Color } -// ModelFunc is an adapter type to allow the use of a color conversion -// function as a Model. If f is such a function, ModelFunc(f) is a Model that -// invokes f to implement the conversion. -type ModelFunc func(Color) Color +// ModelFunc returns a Model that invokes f to implement the conversion. +func ModelFunc(f func(Color) Color) Model { + // Note: using *modelFunc as the implementation + // means that callers can still use comparisons + // like m == RGBAModel. This is not possible if + // we use the func value directly, because funcs + // are no longer comparable. + return &modelFunc{f} +} + +type modelFunc struct { + f func(Color) Color +} -func (f ModelFunc) Convert(c Color) Color { - return f(c) +func (m *modelFunc) Convert(c Color) Color { + return m.f(c) } // RGBAModel is the Model for RGBA colors. diff --git a/libgo/go/image/names.go b/libgo/go/image/names.go index a7ad51d5371..a7d1a579831 100644 --- a/libgo/go/image/names.go +++ b/libgo/go/image/names.go @@ -20,7 +20,7 @@ var ( ) // Uniform is an infinite-sized Image of uniform color. -// It implements both the color.Color and Image interfaces. +// It implements the color.Color, color.ColorModel, and Image interfaces. type Uniform struct { C color.Color } @@ -30,7 +30,11 @@ func (c *Uniform) RGBA() (r, g, b, a uint32) { } func (c *Uniform) ColorModel() color.Model { - return color.ModelFunc(func(color.Color) color.Color { return c.C }) + return c +} + +func (c *Uniform) Convert(color.Color) color.Color { + return c.C } func (c *Uniform) Bounds() Rectangle { return Rectangle{Point{-1e9, -1e9}, Point{1e9, 1e9}} } diff --git a/libgo/go/image/png/writer.go b/libgo/go/image/png/writer.go index 48089ff75c7..641eae1bb8e 100644 --- a/libgo/go/image/png/writer.go +++ b/libgo/go/image/png/writer.go @@ -429,7 +429,7 @@ func Encode(w io.Writer, m image.Image) error { // also rejected. mw, mh := int64(m.Bounds().Dx()), int64(m.Bounds().Dy()) if mw <= 0 || mh <= 0 || mw >= 1<<32 || mh >= 1<<32 { - return FormatError("invalid image size: " + strconv.Itoa64(mw) + "x" + strconv.Itoa64(mw)) + return FormatError("invalid image size: " + strconv.FormatInt(mw, 10) + "x" + strconv.FormatInt(mw, 10)) } var e encoder diff --git a/libgo/go/math/sin.go b/libgo/go/math/sin.go index 9e553a268bd..b2a3f8a4e0e 100644 --- a/libgo/go/math/sin.go +++ b/libgo/go/math/sin.go @@ -110,7 +110,7 @@ var _cos = [...]float64{ // Cos returns the cosine of x. // -// Special conditions are: +// Special cases are: // Cos(±Inf) = NaN // Cos(NaN) = NaN func Cos(x float64) float64 { diff --git a/libgo/go/math/sincos.go b/libgo/go/math/sincos.go index f5412fd726f..74294256beb 100644 --- a/libgo/go/math/sincos.go +++ b/libgo/go/math/sincos.go @@ -8,7 +8,7 @@ package math // Sincos(x) returns Sin(x), Cos(x). // -// Special conditions are: +// Special cases are: // Sincos(±0) = ±0, 1 // Sincos(±Inf) = NaN, NaN // Sincos(NaN) = NaN, NaN diff --git a/libgo/go/math/sinh.go b/libgo/go/math/sinh.go index eaf28a51cd6..139b911fe65 100644 --- a/libgo/go/math/sinh.go +++ b/libgo/go/math/sinh.go @@ -17,6 +17,11 @@ package math */ // Sinh returns the hyperbolic sine of x. +// +// Special cases are: +// Sinh(±0) = ±0 +// Sinh(±Inf) = ±Inf +// Sinh(NaN) = NaN func Sinh(x float64) float64 { // The coefficients are #2029 from Hart & Cheney. (20.36D) const ( @@ -56,6 +61,11 @@ func Sinh(x float64) float64 { } // Cosh returns the hyperbolic cosine of x. +// +// Special cases are: +// Cosh(±0) = 1 +// Cosh(±Inf) = +Inf +// Cosh(NaN) = NaN func Cosh(x float64) float64 { if x < 0 { x = -x diff --git a/libgo/go/math/tan.go b/libgo/go/math/tan.go index 739ee80f76f..76131fcd935 100644 --- a/libgo/go/math/tan.go +++ b/libgo/go/math/tan.go @@ -75,7 +75,7 @@ var _tanQ = [...]float64{ // Tan returns the tangent of x. // -// Special conditions are: +// Special cases are: // Tan(±0) = ±0 // Tan(±Inf) = NaN // Tan(NaN) = NaN diff --git a/libgo/go/math/tanh.go b/libgo/go/math/tanh.go index f4a8a5a4d60..03a641b4da0 100644 --- a/libgo/go/math/tanh.go +++ b/libgo/go/math/tanh.go @@ -12,6 +12,11 @@ package math */ // Tanh computes the hyperbolic tangent of x. +// +// Special cases are: +// Tanh(±0) = ±0 +// Tanh(±Inf) = ±1 +// Tanh(NaN) = NaN func Tanh(x float64) float64 { if x < 0 { x = -x diff --git a/libgo/go/net/http/cgi/child.go b/libgo/go/net/http/cgi/child.go index e188cd4a250..e6c3ef911ab 100644 --- a/libgo/go/net/http/cgi/child.go +++ b/libgo/go/net/http/cgi/child.go @@ -70,7 +70,7 @@ func RequestFromMap(params map[string]string) (*http.Request, error) { r.Host = params["HTTP_HOST"] if lenstr := params["CONTENT_LENGTH"]; lenstr != "" { - clen, err := strconv.Atoi64(lenstr) + clen, err := strconv.ParseInt(lenstr, 10, 64) if err != nil { return nil, errors.New("cgi: bad CONTENT_LENGTH in environment: " + lenstr) } diff --git a/libgo/go/net/http/chunked.go b/libgo/go/net/http/chunked.go index 74c41aabd41..60a478fd8fa 100644 --- a/libgo/go/net/http/chunked.go +++ b/libgo/go/net/http/chunked.go @@ -48,7 +48,7 @@ func (cr *chunkedReader) beginChunk() { if cr.err != nil { return } - cr.n, cr.err = strconv.Btoui64(line, 16) + cr.n, cr.err = strconv.ParseUint(line, 16, 64) if cr.err != nil { return } @@ -147,7 +147,7 @@ func (cw *chunkedWriter) Write(data []byte) (n int, err error) { return 0, nil } - head := strconv.Itob(len(data), 16) + "\r\n" + head := strconv.FormatInt(int64(len(data)), 16) + "\r\n" if _, err = io.WriteString(cw.Wire, head); err != nil { return 0, err diff --git a/libgo/go/net/http/cookie_test.go b/libgo/go/net/http/cookie_test.go index 26bff93f643..712350dfcef 100644 --- a/libgo/go/net/http/cookie_test.go +++ b/libgo/go/net/http/cookie_test.go @@ -81,14 +81,14 @@ var addCookieTests = []struct { "", }, { - []*Cookie{&Cookie{Name: "cookie-1", Value: "v$1"}}, + []*Cookie{{Name: "cookie-1", Value: "v$1"}}, "cookie-1=v$1", }, { []*Cookie{ - &Cookie{Name: "cookie-1", Value: "v$1"}, - &Cookie{Name: "cookie-2", Value: "v$2"}, - &Cookie{Name: "cookie-3", Value: "v$3"}, + {Name: "cookie-1", Value: "v$1"}, + {Name: "cookie-2", Value: "v$2"}, + {Name: "cookie-3", Value: "v$3"}, }, "cookie-1=v$1; cookie-2=v$2; cookie-3=v$3", }, @@ -113,11 +113,11 @@ var readSetCookiesTests = []struct { }{ { Header{"Set-Cookie": {"Cookie-1=v$1"}}, - []*Cookie{&Cookie{Name: "Cookie-1", Value: "v$1", Raw: "Cookie-1=v$1"}}, + []*Cookie{{Name: "Cookie-1", Value: "v$1", Raw: "Cookie-1=v$1"}}, }, { Header{"Set-Cookie": {"NID=99=YsDT5i3E-CXax-; expires=Wed, 23-Nov-2011 01:05:03 GMT; path=/; domain=.google.ch; HttpOnly"}}, - []*Cookie{&Cookie{ + []*Cookie{{ Name: "NID", Value: "99=YsDT5i3E-CXax-", Path: "/", @@ -159,30 +159,30 @@ var readCookiesTests = []struct { Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}}, "", []*Cookie{ - &Cookie{Name: "Cookie-1", Value: "v$1"}, - &Cookie{Name: "c2", Value: "v2"}, + {Name: "Cookie-1", Value: "v$1"}, + {Name: "c2", Value: "v2"}, }, }, { Header{"Cookie": {"Cookie-1=v$1", "c2=v2"}}, "c2", []*Cookie{ - &Cookie{Name: "c2", Value: "v2"}, + {Name: "c2", Value: "v2"}, }, }, { Header{"Cookie": {"Cookie-1=v$1; c2=v2"}}, "", []*Cookie{ - &Cookie{Name: "Cookie-1", Value: "v$1"}, - &Cookie{Name: "c2", Value: "v2"}, + {Name: "Cookie-1", Value: "v$1"}, + {Name: "c2", Value: "v2"}, }, }, { Header{"Cookie": {"Cookie-1=v$1; c2=v2"}}, "c2", []*Cookie{ - &Cookie{Name: "c2", Value: "v2"}, + {Name: "c2", Value: "v2"}, }, }, } diff --git a/libgo/go/net/http/fs.go b/libgo/go/net/http/fs.go index 70e7849f167..1392ca68ad6 100644 --- a/libgo/go/net/http/fs.go +++ b/libgo/go/net/http/fs.go @@ -220,7 +220,7 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec w.Header().Set("Accept-Ranges", "bytes") if w.Header().Get("Content-Encoding") == "" { - w.Header().Set("Content-Length", strconv.Itoa64(size)) + w.Header().Set("Content-Length", strconv.FormatInt(size, 10)) } w.WriteHeader(code) @@ -295,7 +295,7 @@ func parseRange(s string, size int64) ([]httpRange, error) { if start == "" { // If no start is specified, end specifies the // range start relative to the end of the file. - i, err := strconv.Atoi64(end) + i, err := strconv.ParseInt(end, 10, 64) if err != nil { return nil, errors.New("invalid range") } @@ -305,7 +305,7 @@ func parseRange(s string, size int64) ([]httpRange, error) { r.start = size - i r.length = size - r.start } else { - i, err := strconv.Atoi64(start) + i, err := strconv.ParseInt(start, 10, 64) if err != nil || i > size || i < 0 { return nil, errors.New("invalid range") } @@ -314,7 +314,7 @@ func parseRange(s string, size int64) ([]httpRange, error) { // If no end is specified, range extends to end of the file. r.length = size - r.start } else { - i, err := strconv.Atoi64(end) + i, err := strconv.ParseInt(end, 10, 64) if err != nil || r.start > i { return nil, errors.New("invalid range") } diff --git a/libgo/go/net/http/httputil/chunked.go b/libgo/go/net/http/httputil/chunked.go index 69bcc0e816f..29eaf3475f1 100644 --- a/libgo/go/net/http/httputil/chunked.go +++ b/libgo/go/net/http/httputil/chunked.go @@ -50,7 +50,7 @@ func (cr *chunkedReader) beginChunk() { if cr.err != nil { return } - cr.n, cr.err = strconv.Btoui64(line, 16) + cr.n, cr.err = strconv.ParseUint(line, 16, 64) if cr.err != nil { return } @@ -149,7 +149,7 @@ func (cw *chunkedWriter) Write(data []byte) (n int, err error) { return 0, nil } - head := strconv.Itob(len(data), 16) + "\r\n" + head := strconv.FormatInt(int64(len(data)), 16) + "\r\n" if _, err = io.WriteString(cw.Wire, head); err != nil { return 0, err diff --git a/libgo/go/net/http/pprof/pprof.go b/libgo/go/net/http/pprof/pprof.go index 2de147579d1..21eac4743ac 100644 --- a/libgo/go/net/http/pprof/pprof.go +++ b/libgo/go/net/http/pprof/pprof.go @@ -63,7 +63,7 @@ func Heap(w http.ResponseWriter, r *http.Request) { // Profile responds with the pprof-formatted cpu profile. // The package initialization registers it as /debug/pprof/profile. func Profile(w http.ResponseWriter, r *http.Request) { - sec, _ := strconv.Atoi64(r.FormValue("seconds")) + sec, _ := strconv.ParseInt(r.FormValue("seconds"), 10, 64) if sec == 0 { sec = 30 } @@ -111,7 +111,7 @@ func Symbol(w http.ResponseWriter, r *http.Request) { if err == nil { word = word[0 : len(word)-1] // trim + } - pc, _ := strconv.Btoui64(string(word), 0) + pc, _ := strconv.ParseUint(string(word), 0, 64) if pc != 0 { f := runtime.FuncForPC(uintptr(pc)) if f != nil { diff --git a/libgo/go/net/http/server.go b/libgo/go/net/http/server.go index 125f3f214bb..c100e4d5c6d 100644 --- a/libgo/go/net/http/server.go +++ b/libgo/go/net/http/server.go @@ -288,7 +288,7 @@ func (w *response) WriteHeader(code int) { var contentLength int64 if clenStr := w.header.Get("Content-Length"); clenStr != "" { var err error - contentLength, err = strconv.Atoi64(clenStr) + contentLength, err = strconv.ParseInt(clenStr, 10, 64) if err == nil { hasCL = true } else { diff --git a/libgo/go/net/http/transfer.go b/libgo/go/net/http/transfer.go index d25c8fcde42..ef9564af9c5 100644 --- a/libgo/go/net/http/transfer.go +++ b/libgo/go/net/http/transfer.go @@ -147,7 +147,7 @@ func (t *transferWriter) WriteHeader(w io.Writer) (err error) { // TransferEncoding) if t.shouldSendContentLength() { io.WriteString(w, "Content-Length: ") - _, err = io.WriteString(w, strconv.Itoa64(t.ContentLength)+"\r\n") + _, err = io.WriteString(w, strconv.FormatInt(t.ContentLength, 10)+"\r\n") if err != nil { return } @@ -432,7 +432,7 @@ func fixLength(isResponse bool, status int, requestMethod string, header Header, // Logic based on Content-Length cl := strings.TrimSpace(header.Get("Content-Length")) if cl != "" { - n, err := strconv.Atoi64(cl) + n, err := strconv.ParseInt(cl, 10, 64) if err != nil || n < 0 { return -1, &badStringError{"bad Content-Length", cl} } diff --git a/libgo/go/net/http/transport.go b/libgo/go/net/http/transport.go index e622e41f0a2..dc70be43f2d 100644 --- a/libgo/go/net/http/transport.go +++ b/libgo/go/net/http/transport.go @@ -519,17 +519,11 @@ func (pc *persistConn) readLoop() { for alive { pb, err := pc.br.Peek(1) - if err != nil { - if remoteSideClosed(err) && !pc.expectingResponse() { - // Remote side closed on us. (We probably hit their - // max idle timeout) - pc.close() - return - } - } if !pc.expectingResponse() { - log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v", - string(pb), err) + if len(pb) > 0 { + log.Printf("Unsolicited response received on idle HTTP channel starting with %q; err=%v", + string(pb), err) + } pc.close() return } diff --git a/libgo/go/net/http/transport_windows.go b/libgo/go/net/http/transport_windows.go deleted file mode 100644 index c9ef2c2ab6e..00000000000 --- a/libgo/go/net/http/transport_windows.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package http - -import ( - "net" - "syscall" -) - -func init() { - remoteSideClosedFunc = func(err error) (out bool) { - op, ok := err.(*net.OpError) - if ok && op.Op == "WSARecv" && op.Net == "tcp" && op.Err == syscall.Errno(10058) { - // TODO(brainman,rsc): Fix whatever is generating this. - return true - } - return false - } -} diff --git a/libgo/go/net/iprawsock_posix.go b/libgo/go/net/iprawsock_posix.go index 3bb99f9a577..d3cb38a6517 100644 --- a/libgo/go/net/iprawsock_posix.go +++ b/libgo/go/net/iprawsock_posix.go @@ -267,16 +267,6 @@ func ListenIP(netProto string, laddr *IPAddr) (c *IPConn, err error) { return newIPConn(fd), nil } -// BindToDevice binds an IPConn to a network interface. -func (c *IPConn) BindToDevice(device string) error { - if !c.ok() { - return os.EINVAL - } - c.fd.incref() - defer c.fd.decref() - return os.NewSyscallError("setsockopt", syscall.BindToDevice(c.fd.sysfd, device)) -} - // File returns a copy of the underlying os.File, set to blocking mode. // It is the caller's responsibility to close f when finished. // Closing c does not affect f, and closing f does not affect c. diff --git a/libgo/go/net/mail/message.go b/libgo/go/net/mail/message.go index e1afa32062f..bf22c711e49 100644 --- a/libgo/go/net/mail/message.go +++ b/libgo/go/net/mail/message.go @@ -481,7 +481,7 @@ func (qd qDecoder) Read(p []byte) (n int, err error) { if _, err := io.ReadFull(qd.r, qd.scratch[:2]); err != nil { return 0, err } - x, err := strconv.Btoi64(string(qd.scratch[:2]), 16) + x, err := strconv.ParseInt(string(qd.scratch[:2]), 16, 64) if err != nil { return 0, fmt.Errorf("mail: invalid RFC 2047 encoding: %q", qd.scratch[:2]) } diff --git a/libgo/go/net/mail/message_test.go b/libgo/go/net/mail/message_test.go index 1f71cc480af..671ff2efacb 100644 --- a/libgo/go/net/mail/message_test.go +++ b/libgo/go/net/mail/message_test.go @@ -105,7 +105,7 @@ func TestDateParsing(t *testing.T) { t.Errorf("Failed parsing %q: %v", test.dateStr, err) continue } - if !reflect.DeepEqual(date, test.exp) { + if !date.Equal(test.exp) { t.Errorf("Parse of %q: got %+v, want %+v", test.dateStr, date, test.exp) } } @@ -119,14 +119,14 @@ func TestAddressParsing(t *testing.T) { // Bare address { `jdoe@machine.example`, - []*Address{&Address{ + []*Address{{ Address: "jdoe@machine.example", }}, }, // RFC 5322, Appendix A.1.1 { `John Doe <jdoe@machine.example>`, - []*Address{&Address{ + []*Address{{ Name: "John Doe", Address: "jdoe@machine.example", }}, @@ -134,7 +134,7 @@ func TestAddressParsing(t *testing.T) { // RFC 5322, Appendix A.1.2 { `"Joe Q. Public" <john.q.public@example.com>`, - []*Address{&Address{ + []*Address{{ Name: "Joe Q. Public", Address: "john.q.public@example.com", }}, @@ -142,14 +142,14 @@ func TestAddressParsing(t *testing.T) { { `Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>`, []*Address{ - &Address{ + { Name: "Mary Smith", Address: "mary@x.test", }, - &Address{ + { Address: "jdoe@example.org", }, - &Address{ + { Name: "Who?", Address: "one@y.test", }, @@ -158,10 +158,10 @@ func TestAddressParsing(t *testing.T) { { `<boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>`, []*Address{ - &Address{ + { Address: "boss@nil.test", }, - &Address{ + { Name: `Giant; "Big" Box`, Address: "sysservices@example.net", }, @@ -174,7 +174,7 @@ func TestAddressParsing(t *testing.T) { { `=?iso-8859-1?q?J=F6rg_Doe?= <joerg@example.com>`, []*Address{ - &Address{ + { Name: `Jörg Doe`, Address: "joerg@example.com", }, @@ -184,7 +184,7 @@ func TestAddressParsing(t *testing.T) { { `=?utf-8?q?J=C3=B6rg_Doe?= <joerg@example.com>`, []*Address{ - &Address{ + { Name: `Jörg Doe`, Address: "joerg@example.com", }, @@ -194,7 +194,7 @@ func TestAddressParsing(t *testing.T) { { `=?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>`, []*Address{ - &Address{ + { Name: `André Pirard`, Address: "PIRARD@vm1.ulg.ac.be", }, @@ -204,7 +204,7 @@ func TestAddressParsing(t *testing.T) { { `=?ISO-8859-1?B?SvZyZw==?= <joerg@example.com>`, []*Address{ - &Address{ + { Name: `Jörg`, Address: "joerg@example.com", }, @@ -214,7 +214,7 @@ func TestAddressParsing(t *testing.T) { { `=?UTF-8?B?SsO2cmc=?= <joerg@example.com>`, []*Address{ - &Address{ + { Name: `Jörg`, Address: "joerg@example.com", }, diff --git a/libgo/go/net/sock.go b/libgo/go/net/sock.go index 33f11f219c9..777f204b186 100644 --- a/libgo/go/net/sock.go +++ b/libgo/go/net/sock.go @@ -111,11 +111,6 @@ func setReuseAddr(fd *netFD, reuse bool) error { return setsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse)) } -func bindToDevice(fd *netFD, dev string) error { - // TODO(rsc): call setsockopt with null-terminated string pointer - return os.EINVAL -} - func setDontRoute(fd *netFD, dontroute bool) error { fd.incref() defer fd.decref() diff --git a/libgo/go/net/udpsock_posix.go b/libgo/go/net/udpsock_posix.go index 2cfcc609d43..c25ec9c506a 100644 --- a/libgo/go/net/udpsock_posix.go +++ b/libgo/go/net/udpsock_posix.go @@ -240,16 +240,6 @@ func ListenUDP(net string, laddr *UDPAddr) (c *UDPConn, err error) { return newUDPConn(fd), nil } -// BindToDevice binds a UDPConn to a network interface. -func (c *UDPConn) BindToDevice(device string) error { - if !c.ok() { - return os.EINVAL - } - c.fd.incref() - defer c.fd.decref() - return os.NewSyscallError("setsockopt", syscall.BindToDevice(c.fd.sysfd, device)) -} - // File returns a copy of the underlying os.File, set to blocking mode. // It is the caller's responsibility to close f when finished. // Closing c does not affect f, and closing f does not affect c. diff --git a/libgo/go/old/template/parse.go b/libgo/go/old/template/parse.go index b8c806472ee..e1bfa472499 100644 --- a/libgo/go/old/template/parse.go +++ b/libgo/go/old/template/parse.go @@ -424,11 +424,11 @@ func (t *Template) newVariable(words []string) *variableElement { } case '.', '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - v, err := strconv.Btoi64(word, 0) + v, err := strconv.ParseInt(word, 0, 64) if err == nil { args[i] = v } else { - v, err := strconv.Atof64(word) + v, err := strconv.ParseFloat(word, 64) args[i], lerr = v, err } diff --git a/libgo/go/old/template/template_test.go b/libgo/go/old/template/template_test.go index 9462c7ee3cf..a6e0c3e1b4e 100644 --- a/libgo/go/old/template/template_test.go +++ b/libgo/go/old/template/template_test.go @@ -105,108 +105,108 @@ var formatters = FormatterMap{ var tests = []*Test{ // Simple - &Test{"", "", ""}, - &Test{"abc", "abc", ""}, - &Test{"abc\ndef\n", "abc\ndef\n", ""}, - &Test{" {.meta-left} \n", "{", ""}, - &Test{" {.meta-right} \n", "}", ""}, - &Test{" {.space} \n", " ", ""}, - &Test{" {.tab} \n", "\t", ""}, - &Test{" {#comment} \n", "", ""}, - &Test{"\tSome Text\t\n", "\tSome Text\t\n", ""}, - &Test{" {.meta-right} {.meta-right} {.meta-right} \n", " } } } \n", ""}, + {"", "", ""}, + {"abc", "abc", ""}, + {"abc\ndef\n", "abc\ndef\n", ""}, + {" {.meta-left} \n", "{", ""}, + {" {.meta-right} \n", "}", ""}, + {" {.space} \n", " ", ""}, + {" {.tab} \n", "\t", ""}, + {" {#comment} \n", "", ""}, + {"\tSome Text\t\n", "\tSome Text\t\n", ""}, + {" {.meta-right} {.meta-right} {.meta-right} \n", " } } } \n", ""}, // Variables at top level - &Test{ + { in: "{Header}={Integer}\n", out: "Header=77\n", }, - &Test{ + { in: "Pointers: {*HeaderPtr}={*IntegerPtr}\n", out: "Pointers: Header=77\n", }, - &Test{ + { in: "Stars but not pointers: {*Header}={*Integer}\n", out: "Stars but not pointers: Header=77\n", }, - &Test{ + { in: "nil pointer: {*NilPtr}={*Integer}\n", out: "nil pointer: <nil>=77\n", }, - &Test{ + { in: `{"Strings" ":"} {""} {"|"} {"\t\u0123 \x23\\"} {"\"}{\\"}`, out: "Strings: | \t\u0123 \x23\\ \"}{\\", }, - &Test{ + { in: "{`Raw strings` `:`} {``} {`|`} {`\\t\\u0123 \\x23\\`} {`}{\\`}", out: "Raw strings: | \\t\\u0123 \\x23\\ }{\\", }, - &Test{ + { in: "Characters: {'a'} {'\\u0123'} {' '} {'{'} {'|'} {'}'}", out: "Characters: 97 291 32 123 124 125", }, - &Test{ + { in: "Integers: {1} {-2} {+42} {0777} {0x0a}", out: "Integers: 1 -2 42 511 10", }, - &Test{ + { in: "Floats: {.5} {-.5} {1.1} {-2.2} {+42.1} {1e10} {1.2e-3} {1.2e3} {-1.2e3}", out: "Floats: 0.5 -0.5 1.1 -2.2 42.1 1e+10 0.0012 1200 -1200", }, // Method at top level - &Test{ + { in: "ptrmethod={PointerMethod}\n", out: "ptrmethod=ptrmethod!\n", }, - &Test{ + { in: "valmethod={ValueMethod}\n", out: "valmethod=valmethod!\n", }, // Section - &Test{ + { in: "{.section Data }\n" + "some text for the section\n" + "{.end}\n", out: "some text for the section\n", }, - &Test{ + { in: "{.section Data }\n" + "{Header}={Integer}\n" + "{.end}\n", out: "Header=77\n", }, - &Test{ + { in: "{.section Pdata }\n" + "{Header}={Integer}\n" + "{.end}\n", out: "Header=77\n", }, - &Test{ + { in: "{.section Pdata }\n" + "data present\n" + "{.or}\n" + @@ -215,7 +215,7 @@ var tests = []*Test{ out: "data present\n", }, - &Test{ + { in: "{.section Empty }\n" + "data present\n" + "{.or}\n" + @@ -224,7 +224,7 @@ var tests = []*Test{ out: "data not present\n", }, - &Test{ + { in: "{.section Null }\n" + "data present\n" + "{.or}\n" + @@ -233,7 +233,7 @@ var tests = []*Test{ out: "data not present\n", }, - &Test{ + { in: "{.section Pdata }\n" + "{Header}={Integer}\n" + "{.section @ }\n" + @@ -245,20 +245,20 @@ var tests = []*Test{ "Header=77\n", }, - &Test{ + { in: "{.section Data}{.end} {Header}\n", out: " Header\n", }, - &Test{ + { in: "{.section Integer}{@}{.end}", out: "77", }, // Repeated - &Test{ + { in: "{.section Pdata }\n" + "{.repeated section @ }\n" + "{Item}={Value}\n" + @@ -268,7 +268,7 @@ var tests = []*Test{ out: "ItemNumber1=ValueNumber1\n" + "ItemNumber2=ValueNumber2\n", }, - &Test{ + { in: "{.section Pdata }\n" + "{.repeated section @ }\n" + "{Item}={Value}\n" + @@ -280,7 +280,7 @@ var tests = []*Test{ out: "ItemNumber1=ValueNumber1\n" + "ItemNumber2=ValueNumber2\n", }, - &Test{ + { in: "{.section @ }\n" + "{.repeated section Empty }\n" + "{Item}={Value}\n" + @@ -291,7 +291,7 @@ var tests = []*Test{ out: "this should appear: empty field\n", }, - &Test{ + { in: "{.repeated section Pdata }\n" + "{Item}\n" + "{.alternates with}\n" + @@ -302,7 +302,7 @@ var tests = []*Test{ "is\nover\nmultiple\nlines\n" + "ItemNumber2\n", }, - &Test{ + { in: "{.repeated section Pdata }\n" + "{Item}\n" + "{.alternates with}\n" + @@ -313,7 +313,7 @@ var tests = []*Test{ "is\nover\nmultiple\nlines\n" + "ItemNumber2\n", }, - &Test{ + { in: "{.section Pdata }\n" + "{.repeated section @ }\n" + "{Item}={Value}\n" + @@ -327,7 +327,7 @@ var tests = []*Test{ "DIVIDER\n" + "ItemNumber2=ValueNumber2\n", }, - &Test{ + { in: "{.repeated section Vec }\n" + "{@}\n" + "{.end}\n", @@ -336,27 +336,27 @@ var tests = []*Test{ "elt2\n", }, // Same but with a space before {.end}: was a bug. - &Test{ + { in: "{.repeated section Vec }\n" + "{@} {.end}\n", out: "elt1 elt2 \n", }, - &Test{ + { in: "{.repeated section Integer}{.end}", err: "line 1: .repeated: cannot repeat Integer (type int)", }, // Nested names - &Test{ + { in: "{.section @ }\n" + "{InnerT.Item}={InnerT.Value}\n" + "{.end}", out: "ItemNumber1=ValueNumber1\n", }, - &Test{ + { in: "{.section @ }\n" + "{InnerT.Item}={.section InnerT}{.section Value}{@}{.end}{.end}\n" + "{.end}", @@ -364,14 +364,14 @@ var tests = []*Test{ out: "ItemNumber1=ValueNumber1\n", }, - &Test{ + { in: "{.section Emptystring}emptystring{.end}\n" + "{.section Header}header{.end}\n", out: "\nheader\n", }, - &Test{ + { in: "{.section True}1{.or}2{.end}\n" + "{.section False}3{.or}4{.end}\n", @@ -380,32 +380,32 @@ var tests = []*Test{ // Maps - &Test{ + { in: "{Mp.mapkey}\n", out: "Ahoy!\n", }, - &Test{ + { in: "{Innermap.Mp.innerkey}\n", out: "55\n", }, - &Test{ + { in: "{.section Innermap}{.section Mp}{innerkey}{.end}{.end}\n", out: "55\n", }, - &Test{ + { in: "{.section JSON}{.repeated section maps}{a}{b}{.end}{.end}\n", out: "1234\n", }, - &Test{ + { in: "{Stringmap.stringkey1}\n", out: "stringresult\n", }, - &Test{ + { in: "{.repeated section Stringmap}\n" + "{@}\n" + "{.end}", @@ -413,7 +413,7 @@ var tests = []*Test{ out: "stringresult\n" + "stringresult\n", }, - &Test{ + { in: "{.repeated section Stringmap}\n" + "\t{@}\n" + "{.end}", @@ -421,12 +421,12 @@ var tests = []*Test{ out: "\tstringresult\n" + "\tstringresult\n", }, - &Test{ + { in: "{*Ptrmap.stringkey1}\n", out: "pointedToString\n", }, - &Test{ + { in: "{.repeated section Ptrmap}\n" + "{*@}\n" + "{.end}", @@ -437,22 +437,22 @@ var tests = []*Test{ // Interface values - &Test{ + { in: "{Iface}", out: "[1 2 3]", }, - &Test{ + { in: "{.repeated section Iface}{@}{.alternates with} {.end}", out: "1 2 3", }, - &Test{ + { in: "{.section Iface}{@}{.end}", out: "[1 2 3]", }, - &Test{ + { in: "{.section Ifaceptr}{Item} {Value}{.end}", out: "Item Value", diff --git a/libgo/go/os/exec/lp_windows.go b/libgo/go/os/exec/lp_windows.go index ef5bd921668..d09e839a397 100644 --- a/libgo/go/os/exec/lp_windows.go +++ b/libgo/go/os/exec/lp_windows.go @@ -63,11 +63,10 @@ func LookPath(file string) (f string, err error) { } return ``, &Error{file, err} } - if pathenv := os.Getenv(`PATH`); pathenv == `` { - if f, err = findExecutable(`.\`+file, exts); err == nil { - return - } - } else { + if f, err = findExecutable(`.\`+file, exts); err == nil { + return + } + if pathenv := os.Getenv(`PATH`); pathenv != `` { for _, dir := range strings.Split(pathenv, `;`) { if f, err = findExecutable(dir+`\`+file, exts); err == nil { return diff --git a/libgo/go/path/filepath/path_test.go b/libgo/go/path/filepath/path_test.go index 2bd62d34aeb..b5b0dedcd40 100644 --- a/libgo/go/path/filepath/path_test.go +++ b/libgo/go/path/filepath/path_test.go @@ -259,19 +259,19 @@ type Node struct { var tree = &Node{ "testdata", []*Node{ - &Node{"a", nil, 0}, - &Node{"b", []*Node{}, 0}, - &Node{"c", nil, 0}, - &Node{ + {"a", nil, 0}, + {"b", []*Node{}, 0}, + {"c", nil, 0}, + { "d", []*Node{ - &Node{"x", nil, 0}, - &Node{"y", []*Node{}, 0}, - &Node{ + {"x", nil, 0}, + {"y", []*Node{}, 0}, + { "z", []*Node{ - &Node{"u", nil, 0}, - &Node{"v", nil, 0}, + {"u", nil, 0}, + {"v", nil, 0}, }, 0, }, diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index cf31d1ba39d..7d1cb094e5c 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -64,7 +64,7 @@ var typeTests = []pair{ {struct{ x (**integer) }{}, "**reflect_test.integer"}, {struct{ x ([32]int32) }{}, "[32]int32"}, {struct{ x ([]int8) }{}, "[]int8"}, - {struct{ x (map[string]int32) }{}, "map[string] int32"}, + {struct{ x (map[string]int32) }{}, "map[string]int32"}, {struct{ x (chan<- string) }{}, "chan<- string"}, {struct { x struct { @@ -180,7 +180,7 @@ var valueTests = []pair{ {new(**int8), "**int8(0)"}, {new([5]int32), "[5]int32{0, 0, 0, 0, 0}"}, {new(**integer), "**reflect_test.integer(0)"}, - {new(map[string]int32), "map[string] int32{<can't iterate on maps>}"}, + {new(map[string]int32), "map[string]int32{<can't iterate on maps>}"}, {new(chan<- string), "chan<- string"}, {new(func(a int8, b int32)), "func(int8, int32)(0)"}, {new(struct { @@ -419,7 +419,7 @@ func TestAll(t *testing.T) { testType(t, 8, typ.Elem(), "int32") typ = TypeOf((map[string]*int32)(nil)) - testType(t, 9, typ, "map[string] *int32") + testType(t, 9, typ, "map[string]*int32") mtyp := typ testType(t, 10, mtyp.Key(), "string") testType(t, 11, mtyp.Elem(), "*int32") @@ -468,8 +468,8 @@ func TestInterfaceValue(t *testing.T) { func TestFunctionValue(t *testing.T) { var x interface{} = func() {} v := ValueOf(x) - if v.Interface() != v.Interface() || v.Interface() != x { - t.Fatalf("TestFunction != itself") + if fmt.Sprint(v.Interface()) != fmt.Sprint(x) { + t.Fatalf("TestFunction returned wrong pointer") } assert(t, v.Type().String(), "func()") } diff --git a/libgo/go/reflect/tostring_test.go b/libgo/go/reflect/tostring_test.go index 5f5c52b778a..7486a9bfca3 100644 --- a/libgo/go/reflect/tostring_test.go +++ b/libgo/go/reflect/tostring_test.go @@ -23,14 +23,14 @@ func valueToString(val Value) string { typ := val.Type() switch val.Kind() { case Int, Int8, Int16, Int32, Int64: - return strconv.Itoa64(val.Int()) + return strconv.FormatInt(val.Int(), 10) case Uint, Uint8, Uint16, Uint32, Uint64, Uintptr: - return strconv.Uitoa64(val.Uint()) + return strconv.FormatUint(val.Uint(), 10) case Float32, Float64: - return strconv.Ftoa64(val.Float(), 'g', -1) + return strconv.FormatFloat(val.Float(), 'g', -1, 64) case Complex64, Complex128: c := val.Complex() - return strconv.Ftoa64(real(c), 'g', -1) + "+" + strconv.Ftoa64(imag(c), 'g', -1) + "i" + return strconv.FormatFloat(real(c), 'g', -1, 64) + "+" + strconv.FormatFloat(imag(c), 'g', -1, 64) + "i" case String: return val.String() case Bool: @@ -88,7 +88,7 @@ func valueToString(val Value) string { return typ.String() + "(" + valueToString(val.Elem()) + ")" case Func: v := val - return typ.String() + "(" + strconv.Uitoa64(uint64(v.Pointer())) + ")" + return typ.String() + "(" + strconv.FormatUint(uint64(v.Pointer()), 10) + ")" default: panic("valueToString: can't print type " + typ.String()) } diff --git a/libgo/go/regexp/syntax/prog.go b/libgo/go/regexp/syntax/prog.go index f5b697a59ae..84ebb835581 100644 --- a/libgo/go/regexp/syntax/prog.go +++ b/libgo/go/regexp/syntax/prog.go @@ -267,7 +267,7 @@ func dumpProg(b *bytes.Buffer, p *Prog) { } func u32(i uint32) string { - return strconv.Uitoa64(uint64(i)) + return strconv.FormatUint(uint64(i), 10) } func dumpInst(b *bytes.Buffer, i *Inst) { diff --git a/libgo/go/regexp/syntax/regexp.go b/libgo/go/regexp/syntax/regexp.go index b5ddab1d16b..adcfe294495 100644 --- a/libgo/go/regexp/syntax/regexp.go +++ b/libgo/go/regexp/syntax/regexp.go @@ -277,7 +277,7 @@ func escape(b *bytes.Buffer, r rune, force bool) { default: if r < 0x100 { b.WriteString(`\x`) - s := strconv.Itob(int(r), 16) + s := strconv.FormatInt(int64(r), 16) if len(s) == 1 { b.WriteRune('0') } @@ -285,7 +285,7 @@ func escape(b *bytes.Buffer, r rune, force bool) { break } b.WriteString(`\x{`) - b.WriteString(strconv.Itob(int(r), 16)) + b.WriteString(strconv.FormatInt(int64(r), 16)) b.WriteString(`}`) } } diff --git a/libgo/go/strconv/atob.go b/libgo/go/strconv/atob.go index e2d87bc0f2b..1508118d2ac 100644 --- a/libgo/go/strconv/atob.go +++ b/libgo/go/strconv/atob.go @@ -4,10 +4,10 @@ package strconv -// Atob returns the boolean value represented by the string. +// ParseBool returns the boolean value represented by the string. // It accepts 1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False. // Any other value returns an error. -func Atob(str string) (value bool, err error) { +func ParseBool(str string) (value bool, err error) { switch str { case "1", "t", "T", "true", "TRUE", "True": return true, nil @@ -17,10 +17,19 @@ func Atob(str string) (value bool, err error) { return false, &NumError{str, ErrSyntax} } -// Btoa returns "true" or "false" according to the value of the boolean argument -func Btoa(b bool) string { +// FormatBool returns "true" or "false" according to the value of b +func FormatBool(b bool) string { if b { return "true" } return "false" } + +// AppendBool appends "true" or "false", according to the value of b, +// to dst and returns the extended buffer. +func AppendBool(dst []byte, b bool) []byte { + if b { + return append(dst, "true"...) + } + return append(dst, "false"...) +} diff --git a/libgo/go/strconv/atob_test.go b/libgo/go/strconv/atob_test.go index 2f31eb5e071..a7c1454eb1e 100644 --- a/libgo/go/strconv/atob_test.go +++ b/libgo/go/strconv/atob_test.go @@ -32,9 +32,9 @@ var atobtests = []atobTest{ {"True", true, nil}, } -func TestAtob(t *testing.T) { +func TestParseBool(t *testing.T) { for _, test := range atobtests { - b, e := Atob(test.in) + b, e := ParseBool(test.in) if test.err != nil { // expect an error if e == nil { diff --git a/libgo/go/strconv/atof.go b/libgo/go/strconv/atof.go index 06dae8564db..1642c18d748 100644 --- a/libgo/go/strconv/atof.go +++ b/libgo/go/strconv/atof.go @@ -338,21 +338,7 @@ func (d *decimal) atof32() (f float32, ok bool) { return } -// Atof32 converts the string s to a 32-bit floating-point number. -// -// If s is well-formed and near a valid floating point number, -// Atof32 returns the nearest floating point number rounded -// using IEEE754 unbiased rounding. -// -// The errors that Atof32 returns have concrete type *NumError -// and include err.Num = s. -// -// If s is not syntactically well-formed, Atof32 returns err.Error = ErrSyntax. -// -// If s is syntactically well-formed but is more than 1/2 ULP -// away from the largest floating point number of the given size, -// Atof32 returns f = ±Inf, err.Error = ErrRange. -func Atof32(s string) (f float32, err error) { +func atof32(s string) (f float32, err error) { if val, ok := special(s); ok { return float32(val), nil } @@ -374,10 +360,7 @@ func Atof32(s string) (f float32, err error) { return f, err } -// Atof64 converts the string s to a 64-bit floating-point number. -// Except for the type of its result, its definition is the same as that -// of Atof32. -func Atof64(s string) (f float64, err error) { +func atof64(s string) (f float64, err error) { if val, ok := special(s); ok { return val, nil } @@ -399,14 +382,28 @@ func Atof64(s string) (f float64, err error) { return f, err } -// AtofN converts the string s to a 64-bit floating-point number, -// but it rounds the result assuming that it will be stored in a value -// of n bits (32 or 64). -func AtofN(s string, n int) (f float64, err error) { - if n == 32 { - f1, err1 := Atof32(s) +// ParseFloat converts the string s to a floating-point number +// with the precision specified by bitSize: 32 for float32, or 64 for float64. +// When bitSize=32, the result still has type float64, but it will be +// convertible to float32 without changing its value. +// +// If s is well-formed and near a valid floating point number, +// ParseFloat returns the nearest floating point number rounded +// using IEEE754 unbiased rounding. +// +// The errors that ParseFloat returns have concrete type *NumError +// and include err.Num = s. +// +// If s is not syntactically well-formed, ParseFloat returns err.Error = ErrSyntax. +// +// If s is syntactically well-formed but is more than 1/2 ULP +// away from the largest floating point number of the given size, +// ParseFloat returns f = ±Inf, err.Error = ErrRange. +func ParseFloat(s string, bitSize int) (f float64, err error) { + if bitSize == 32 { + f1, err1 := atof32(s) return float64(f1), err1 } - f1, err1 := Atof64(s) + f1, err1 := atof64(s) return f1, err1 } diff --git a/libgo/go/strconv/atof_test.go b/libgo/go/strconv/atof_test.go index 871bf0cd5e6..a9820d1bbad 100644 --- a/libgo/go/strconv/atof_test.go +++ b/libgo/go/strconv/atof_test.go @@ -128,33 +128,23 @@ func testAtof(t *testing.T, opt bool) { oldopt := SetOptimize(opt) for i := 0; i < len(atoftests); i++ { test := &atoftests[i] - out, err := Atof64(test.in) - outs := Ftoa64(out, 'g', -1) + out, err := ParseFloat(test.in, 64) + outs := FormatFloat(out, 'g', -1, 64) if outs != test.out || !reflect.DeepEqual(err, test.err) { - t.Errorf("Atof64(%v) = %v, %v want %v, %v", - test.in, out, err, test.out, test.err) - } - - out, err = AtofN(test.in, 64) - outs = FtoaN(out, 'g', -1, 64) - if outs != test.out || !reflect.DeepEqual(err, test.err) { - t.Errorf("AtofN(%v, 64) = %v, %v want %v, %v", + t.Errorf("ParseFloat(%v, 64) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } if float64(float32(out)) == out { - out32, err := Atof32(test.in) - outs := Ftoa32(out32, 'g', -1) - if outs != test.out || !reflect.DeepEqual(err, test.err) { - t.Errorf("Atof32(%v) = %v, %v want %v, %v # %v", - test.in, out32, err, test.out, test.err, out) + out, err := ParseFloat(test.in, 32) + out32 := float32(out) + if float64(out32) != out { + t.Errorf("ParseFloat(%v, 32) = %v, not a float32 (closest is %v)", test.in, out, float64(out32)) + continue } - - out, err := AtofN(test.in, 32) - out32 = float32(out) - outs = FtoaN(float64(out32), 'g', -1, 32) + outs := FormatFloat(float64(out32), 'g', -1, 32) if outs != test.out || !reflect.DeepEqual(err, test.err) { - t.Errorf("AtofN(%v, 32) = %v, %v want %v, %v # %v", + t.Errorf("ParseFloat(%v, 32) = %v, %v want %v, %v # %v", test.in, out32, err, test.out, test.err, out) } } @@ -168,24 +158,24 @@ func TestAtofSlow(t *testing.T) { testAtof(t, false) } func BenchmarkAtof64Decimal(b *testing.B) { for i := 0; i < b.N; i++ { - Atof64("33909") + ParseFloat("33909", 64) } } func BenchmarkAtof64Float(b *testing.B) { for i := 0; i < b.N; i++ { - Atof64("339.7784") + ParseFloat("339.7784", 64) } } func BenchmarkAtof64FloatExp(b *testing.B) { for i := 0; i < b.N; i++ { - Atof64("-5.09e75") + ParseFloat("-5.09e75", 64) } } func BenchmarkAtof64Big(b *testing.B) { for i := 0; i < b.N; i++ { - Atof64("123456789123456789123456789") + ParseFloat("123456789123456789123456789", 64) } } diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go index 2c6c3d58de3..438d496948d 100644 --- a/libgo/go/strconv/atoi.go +++ b/libgo/go/strconv/atoi.go @@ -20,15 +20,9 @@ type NumError struct { func (e *NumError) Error() string { return `parsing "` + e.Num + `": ` + e.Err.Error() } -func computeIntsize() uint { - siz := uint(8) - for 1<<siz != 0 { - siz *= 2 - } - return siz -} +const intSize = 32 << uint(^uint(0)>>63) -var IntSize = computeIntsize() +const IntSize = intSize // number of bits in int, uint (32 or 64) // Return the first number n such that n*base >= 1<<64. func cutoff64(base int) uint64 { @@ -38,17 +32,13 @@ func cutoff64(base int) uint64 { return (1<<64-1)/uint64(base) + 1 } -// Btoui64 interprets a string s in an arbitrary base b (2 to 36) -// and returns the corresponding value n. If b == 0, the base -// is taken from the string prefix: base 16 for "0x", base 8 for "0", -// and base 10 otherwise. -// -// The errors that Btoui64 returns have concrete type *NumError -// and include err.Num = s. If s is empty or contains invalid -// digits, err.Error = ErrSyntax; if the value corresponding -// to s cannot be represented by a uint64, err.Error = ErrRange. -func Btoui64(s string, b int) (n uint64, err error) { - var cutoff uint64 +// ParseUint is like ParseInt but for unsigned numbers. +func ParseUint(s string, b int, bitSize int) (n uint64, err error) { + var cutoff, maxVal uint64 + + if bitSize == 0 { + bitSize = int(IntSize) + } s0 := s switch { @@ -82,6 +72,7 @@ func Btoui64(s string, b int) (n uint64, err error) { n = 0 cutoff = cutoff64(b) + maxVal = 1<<uint(bitSize) - 1 for i := 0; i < len(s); i++ { var v byte @@ -113,7 +104,7 @@ func Btoui64(s string, b int) (n uint64, err error) { n *= uint64(b) n1 := n + uint64(v) - if n1 < n { + if n1 < n || n1 > maxVal { // n+v overflows n = 1<<64 - 1 err = ErrRange @@ -128,18 +119,25 @@ Error: return n, &NumError{s0, err} } -// Atoui64 interprets a string s as a decimal number and -// returns the corresponding value n. +// ParseInt interprets a string s in an arbitrary base b (2 to 36) +// and returns the corresponding value n. If b == 0, the base +// is taken from the string prefix: base 16 for "0x", base 8 for "0", +// and base 10 otherwise. // -// Atoui64 returns err.Error = ErrSyntax if s is empty or contains invalid digits. -// It returns err.Error = ErrRange if s cannot be represented by a uint64. -func Atoui64(s string) (n uint64, err error) { - return Btoui64(s, 10) -} +// The bitSize argument specifies the integer type +// that the result must fit into. Bit sizes 0, 8, 16, 32, and 64 +// correspond to int, int8, int16, int32, and int64. +// +// The errors that ParseInt returns have concrete type *NumError +// and include err.Num = s. If s is empty or contains invalid +// digits, err.Error = ErrSyntax; if the value corresponding +// to s cannot be represented by a signed integer of the +// given size, err.Error = ErrRange. +func ParseInt(s string, base int, bitSize int) (i int64, err error) { + if bitSize == 0 { + bitSize = int(IntSize) + } -// Btoi64 is like Btoui64 but allows signed numbers and -// returns its result in an int64. -func Btoi64(s string, base int) (i int64, err error) { // Empty string bad. if len(s) == 0 { return 0, &NumError{s, ErrSyntax} @@ -157,16 +155,17 @@ func Btoi64(s string, base int) (i int64, err error) { // Convert unsigned and check range. var un uint64 - un, err = Btoui64(s, base) + un, err = ParseUint(s, base, bitSize) if err != nil && err.(*NumError).Err != ErrRange { err.(*NumError).Num = s0 return 0, err } - if !neg && un >= 1<<63 { - return 1<<63 - 1, &NumError{s0, ErrRange} + cutoff := uint64(1 << uint(bitSize-1)) + if !neg && un >= cutoff { + return int64(cutoff - 1), &NumError{s0, ErrRange} } - if neg && un > 1<<63 { - return -1 << 63, &NumError{s0, ErrRange} + if neg && un > cutoff { + return -int64(cutoff), &NumError{s0, ErrRange} } n := int64(un) if neg { @@ -175,35 +174,8 @@ func Btoi64(s string, base int) (i int64, err error) { return n, nil } -// Atoi64 is like Atoui64 but allows signed numbers and -// returns its result in an int64. -func Atoi64(s string) (i int64, err error) { return Btoi64(s, 10) } - -// Atoui is like Atoui64 but returns its result as a uint. -func Atoui(s string) (i uint, err error) { - i1, e1 := Atoui64(s) - if e1 != nil && e1.(*NumError).Err != ErrRange { - return 0, e1 - } - i = uint(i1) - if uint64(i) != i1 { - return ^uint(0), &NumError{s, ErrRange} - } - return i, nil -} - -// Atoi is like Atoi64 but returns its result as an int. +// Atoi is shorthand for ParseInt(s, 10, 0). func Atoi(s string) (i int, err error) { - i1, e1 := Atoi64(s) - if e1 != nil && e1.(*NumError).Err != ErrRange { - return 0, e1 - } - i = int(i1) - if int64(i) != i1 { - if i1 < 0 { - return -1 << (IntSize - 1), &NumError{s, ErrRange} - } - return 1<<(IntSize-1) - 1, &NumError{s, ErrRange} - } - return i, nil + i64, err := ParseInt(s, 10, 0) + return int(i64), err } diff --git a/libgo/go/strconv/atoi_test.go b/libgo/go/strconv/atoi_test.go index 9ee11b71023..2d06efed0de 100644 --- a/libgo/go/strconv/atoi_test.go +++ b/libgo/go/strconv/atoi_test.go @@ -187,10 +187,10 @@ func init() { } } -func TestAtoui64(t *testing.T) { +func TestParseUint64(t *testing.T) { for i := range atoui64tests { test := &atoui64tests[i] - out, err := Atoui64(test.in) + out, err := ParseUint(test.in, 10, 64) if test.out != out || !reflect.DeepEqual(test.err, err) { t.Errorf("Atoui64(%q) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) @@ -198,21 +198,21 @@ func TestAtoui64(t *testing.T) { } } -func TestBtoui64(t *testing.T) { +func TestParseUint64Base(t *testing.T) { for i := range btoui64tests { test := &btoui64tests[i] - out, err := Btoui64(test.in, 0) + out, err := ParseUint(test.in, 0, 64) if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("Btoui64(%q) = %v, %v want %v, %v", + t.Errorf("ParseUint(%q) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } } -func TestAtoi64(t *testing.T) { +func TestParseInt64(t *testing.T) { for i := range atoi64tests { test := &atoi64tests[i] - out, err := Atoi64(test.in) + out, err := ParseInt(test.in, 10, 64) if test.out != out || !reflect.DeepEqual(test.err, err) { t.Errorf("Atoi64(%q) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) @@ -220,23 +220,23 @@ func TestAtoi64(t *testing.T) { } } -func TestBtoi64(t *testing.T) { +func TestParseInt64Base(t *testing.T) { for i := range btoi64tests { test := &btoi64tests[i] - out, err := Btoi64(test.in, 0) + out, err := ParseInt(test.in, 0, 64) if test.out != out || !reflect.DeepEqual(test.err, err) { - t.Errorf("Btoi64(%q) = %v, %v want %v, %v", + t.Errorf("ParseInt(%q) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) } } } -func TestAtoui(t *testing.T) { +func TestParseUint(t *testing.T) { switch IntSize { case 32: for i := range atoui32tests { test := &atoui32tests[i] - out, err := Atoui(test.in) + out, err := ParseUint(test.in, 10, 0) if test.out != uint32(out) || !reflect.DeepEqual(test.err, err) { t.Errorf("Atoui(%q) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) @@ -245,7 +245,7 @@ func TestAtoui(t *testing.T) { case 64: for i := range atoui64tests { test := &atoui64tests[i] - out, err := Atoui(test.in) + out, err := ParseUint(test.in, 10, 0) if test.out != uint64(out) || !reflect.DeepEqual(test.err, err) { t.Errorf("Atoui(%q) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) @@ -254,12 +254,12 @@ func TestAtoui(t *testing.T) { } } -func TestAtoi(t *testing.T) { +func TestParseInt(t *testing.T) { switch IntSize { case 32: for i := range atoi32tests { test := &atoi32tests[i] - out, err := Atoi(test.in) + out, err := ParseInt(test.in, 10, 0) if test.out != int32(out) || !reflect.DeepEqual(test.err, err) { t.Errorf("Atoi(%q) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) @@ -268,7 +268,7 @@ func TestAtoi(t *testing.T) { case 64: for i := range atoi64tests { test := &atoi64tests[i] - out, err := Atoi(test.in) + out, err := ParseInt(test.in, 10, 0) if test.out != int64(out) || !reflect.DeepEqual(test.err, err) { t.Errorf("Atoi(%q) = %v, %v want %v, %v", test.in, out, err, test.out, test.err) @@ -279,24 +279,24 @@ func TestAtoi(t *testing.T) { func BenchmarkAtoi(b *testing.B) { for i := 0; i < b.N; i++ { - Atoi("12345678") + ParseInt("12345678", 10, 0) } } func BenchmarkAtoiNeg(b *testing.B) { for i := 0; i < b.N; i++ { - Atoi("-12345678") + ParseInt("-12345678", 10, 0) } } func BenchmarkAtoi64(b *testing.B) { for i := 0; i < b.N; i++ { - Atoi64("12345678901234") + ParseInt("12345678901234", 10, 64) } } func BenchmarkAtoi64Neg(b *testing.B) { for i := 0; i < b.N; i++ { - Atoi64("-12345678901234") + ParseInt("-12345678901234", 10, 64) } } diff --git a/libgo/go/strconv/fp_test.go b/libgo/go/strconv/fp_test.go index 9785ca6916d..47877e373aa 100644 --- a/libgo/go/strconv/fp_test.go +++ b/libgo/go/strconv/fp_test.go @@ -31,7 +31,7 @@ func pow2(i int) float64 { func myatof64(s string) (f float64, ok bool) { a := strings.SplitN(s, "p", 2) if len(a) == 2 { - n, err := strconv.Atoi64(a[0]) + n, err := strconv.ParseInt(a[0], 10, 64) if err != nil { return 0, false } @@ -63,7 +63,7 @@ func myatof64(s string) (f float64, ok bool) { } return v * pow2(e), true } - f1, err := strconv.Atof64(s) + f1, err := strconv.ParseFloat(s, 64) if err != nil { return 0, false } @@ -87,7 +87,8 @@ func myatof32(s string) (f float32, ok bool) { } return float32(float64(n) * pow2(e)), true } - f1, err1 := strconv.Atof32(s) + f64, err1 := strconv.ParseFloat(s, 32) + f1 := float32(f64) if err1 != nil { return 0, false } diff --git a/libgo/go/strconv/ftoa.go b/libgo/go/strconv/ftoa.go index 8342b6abe79..e1ea0a35038 100644 --- a/libgo/go/strconv/ftoa.go +++ b/libgo/go/strconv/ftoa.go @@ -22,8 +22,10 @@ type floatInfo struct { var float32info = floatInfo{23, 8, -127} var float64info = floatInfo{52, 11, -1023} -// Ftoa32 converts the 32-bit floating-point number f to a string, -// according to the format fmt and precision prec. +// FormatFloat converts the floating-point number f to a string, +// according to the format fmt and precision prec. It rounds the +// result assuming that the original was obtained from a floating-point +// value of bitSize bits (32 for float32, 64 for float64). // // The format fmt is one of // 'b' (-ddddp±ddd, a binary exponent), @@ -43,24 +45,17 @@ var float64info = floatInfo{52, 11, -1023} // Ftoa32(f) is not the same as Ftoa64(float32(f)), // because correct rounding and the number of digits // needed to identify f depend on the precision of the representation. -func Ftoa32(f float32, fmt byte, prec int) string { - return genericFtoa(uint64(math.Float32bits(f)), fmt, prec, &float32info) -} - -// Ftoa64 is like Ftoa32 but converts a 64-bit floating-point number. -func Ftoa64(f float64, fmt byte, prec int) string { +func FormatFloat(f float64, fmt byte, prec int, n int) string { + if n == 32 { + return genericFtoa(uint64(math.Float32bits(float32(f))), fmt, prec, &float32info) + } return genericFtoa(math.Float64bits(f), fmt, prec, &float64info) } -// FtoaN converts the 64-bit floating-point number f to a string, -// according to the format fmt and precision prec, but it rounds the -// result assuming that it was obtained from a floating-point value -// of n bits (32 or 64). -func FtoaN(f float64, fmt byte, prec int, n int) string { - if n == 32 { - return Ftoa32(float32(f), fmt, prec) - } - return Ftoa64(f, fmt, prec) +// AppendFloat appends the string form of the floating-point number f, +// as generated by FormatFloat, to dst and returns the extended buffer. +func AppendFloat(dst []byte, f float64, fmt byte, prec int, n int) []byte { + return append(dst, FormatFloat(f, fmt, prec, n)...) } func genericFtoa(bits uint64, fmt byte, prec int, flt *floatInfo) string { diff --git a/libgo/go/strconv/ftoa_test.go b/libgo/go/strconv/ftoa_test.go index 8bac5da4526..02206d5ad25 100644 --- a/libgo/go/strconv/ftoa_test.go +++ b/libgo/go/strconv/ftoa_test.go @@ -128,47 +128,47 @@ var ftoatests = []ftoaTest{ func TestFtoa(t *testing.T) { for i := 0; i < len(ftoatests); i++ { test := &ftoatests[i] - s := Ftoa64(test.f, test.fmt, test.prec) - if s != test.s { - t.Error("test", test.f, string(test.fmt), test.prec, "want", test.s, "got", s) - } - s = FtoaN(test.f, test.fmt, test.prec, 64) + s := FormatFloat(test.f, test.fmt, test.prec, 64) if s != test.s { t.Error("testN=64", test.f, string(test.fmt), test.prec, "want", test.s, "got", s) } + x := AppendFloat([]byte("abc"), test.f, test.fmt, test.prec, 64) + if string(x) != "abc"+test.s { + t.Error("AppendFloat testN=64", test.f, string(test.fmt), test.prec, "want", "abc"+test.s, "got", string(x)) + } if float64(float32(test.f)) == test.f && test.fmt != 'b' { - s := Ftoa32(float32(test.f), test.fmt, test.prec) - if s != test.s { - t.Error("test32", test.f, string(test.fmt), test.prec, "want", test.s, "got", s) - } - s = FtoaN(test.f, test.fmt, test.prec, 32) + s := FormatFloat(test.f, test.fmt, test.prec, 32) if s != test.s { t.Error("testN=32", test.f, string(test.fmt), test.prec, "want", test.s, "got", s) } + x := AppendFloat([]byte("abc"), test.f, test.fmt, test.prec, 32) + if string(x) != "abc"+test.s { + t.Error("AppendFloat testN=32", test.f, string(test.fmt), test.prec, "want", "abc"+test.s, "got", string(x)) + } } } } func BenchmarkFtoa64Decimal(b *testing.B) { for i := 0; i < b.N; i++ { - Ftoa64(33909, 'g', -1) + FormatFloat(33909, 'g', -1, 64) } } func BenchmarkFtoa64Float(b *testing.B) { for i := 0; i < b.N; i++ { - Ftoa64(339.7784, 'g', -1) + FormatFloat(339.7784, 'g', -1, 64) } } func BenchmarkFtoa64FloatExp(b *testing.B) { for i := 0; i < b.N; i++ { - Ftoa64(-5.09e75, 'g', -1) + FormatFloat(-5.09e75, 'g', -1, 64) } } func BenchmarkFtoa64Big(b *testing.B) { for i := 0; i < b.N; i++ { - Ftoa64(123456789123456789123456789, 'g', -1) + FormatFloat(123456789123456789123456789, 'g', -1, 64) } } diff --git a/libgo/go/strconv/itoa.go b/libgo/go/strconv/itoa.go index a0a7496641e..65229f704b8 100644 --- a/libgo/go/strconv/itoa.go +++ b/libgo/go/strconv/itoa.go @@ -4,54 +4,110 @@ package strconv -// Uitob64 returns the string representation of i in the given base. -func Uitob64(u uint64, base uint) string { - if base < 2 || 36 < base { - panic("invalid base " + Uitoa(base)) - } - if u == 0 { - return "0" - } +// FormatUint returns the string representation of i in the given base. +func FormatUint(i uint64, base int) string { + _, s := formatBits(nil, i, base, false, false) + return s +} - // Assemble decimal in reverse order. - var buf [64]byte - j := len(buf) - b := uint64(base) - for u > 0 { - j-- - buf[j] = "0123456789abcdefghijklmnopqrstuvwxyz"[u%b] - u /= b - } +// FormatInt returns the string representation of i in the given base. +func FormatInt(i int64, base int) string { + _, s := formatBits(nil, uint64(i), base, i < 0, false) + return s +} + +// Itoa is shorthand for FormatInt(i, 10). +func Itoa(i int) string { + return FormatInt(int64(i), 10) +} + +// AppendInt appends the string form of the integer i, +// as generated by FormatInt, to dst and returns the extended buffer. +func AppendInt(dst []byte, i int64, base int) []byte { + dst, _ = formatBits(dst, uint64(i), base, i < 0, true) + return dst +} - return string(buf[j:]) +// AppendUint appends the string form of the unsigned integer i, +// as generated by FormatUint, to dst and returns the extended buffer. +func AppendUint(dst []byte, i uint64, base int) []byte { + dst, _ = formatBits(dst, i, base, false, true) + return dst } -// Itob64 returns the string representation of i in the given base. -func Itob64(i int64, base uint) string { - if i == 0 { - return "0" +const digits = "0123456789abcdefghijklmnopqrstuvwxyz" + +var shifts = [len(digits) + 1]uint{ + 1 << 1: 1, + 1 << 2: 2, + 1 << 3: 3, + 1 << 4: 4, + 1 << 5: 5, +} + +// formatBits computes the string representation of u in the given base. +// If negative is set, u is treated as negative int64 value. If append_ +// is set, the string is appended to dst and the resulting byte slice is +// returned as the first result value; otherwise the string is returned +// as the second result value. +// +func formatBits(dst []byte, u uint64, base int, negative, append_ bool) (d []byte, s string) { + if base < 2 || base > len(digits) { + panic("invalid base") } + // 2 <= base && base <= len(digits) - if i < 0 { - return "-" + Uitob64(-uint64(i), base) + var a [64 + 1]byte // +1 for sign of 64bit value in base 2 + i := len(a) + + if negative { + u = -u } - return Uitob64(uint64(i), base) -} -// Itoa64 returns the decimal string representation of i. -func Itoa64(i int64) string { return Itob64(i, 10) } + // convert bits + if base == 10 { + // common case: use constant 10 for / and % because + // the compiler can optimize it into a multiply+shift + for u >= 10 { + i-- + a[i] = digits[u%10] + u /= 10 + } -// Uitoa64 returns the decimal string representation of i. -func Uitoa64(i uint64) string { return Uitob64(i, 10) } + } else if s := shifts[base]; s > 0 { + // base is power of 2: use shifts and masks instead of / and % + b := uint64(base) + m := uintptr(b) - 1 // == 1<<s - 1 + for u >= b { + i-- + a[i] = digits[uintptr(u)&m] + u >>= s + } -// Uitob returns the string representation of i in the given base. -func Uitob(i uint, base uint) string { return Uitob64(uint64(i), base) } + } else { + // general case + b := uint64(base) + for u >= b { + i-- + a[i] = digits[u%b] + u /= b + } + } -// Itob returns the string representation of i in the given base. -func Itob(i int, base uint) string { return Itob64(int64(i), base) } + // u < base + i-- + a[i] = digits[uintptr(u)] -// Itoa returns the decimal string representation of i. -func Itoa(i int) string { return Itob64(int64(i), 10) } + // add sign, if any + if negative { + i-- + a[i] = '-' + } -// Uitoa returns the decimal string representation of i. -func Uitoa(i uint) string { return Uitob64(uint64(i), 10) } + if append_ { + d = append(dst, a[i:]...) + return + } + s = string(a[i:]) + return +} diff --git a/libgo/go/strconv/itoa_test.go b/libgo/go/strconv/itoa_test.go index 8514b21e47c..e0213ae9afe 100644 --- a/libgo/go/strconv/itoa_test.go +++ b/libgo/go/strconv/itoa_test.go @@ -11,7 +11,7 @@ import ( type itob64Test struct { in int64 - base uint + base int out string } @@ -60,73 +60,43 @@ var itob64tests = []itob64Test{ func TestItoa(t *testing.T) { for _, test := range itob64tests { - s := Itob64(test.in, test.base) + s := FormatInt(test.in, test.base) if s != test.out { - t.Errorf("Itob64(%v, %v) = %v want %v", + t.Errorf("FormatInt(%v, %v) = %v want %v", test.in, test.base, s, test.out) } - - if test.in >= 0 { - s := Uitob64(uint64(test.in), test.base) - if s != test.out { - t.Errorf("Uitob64(%v, %v) = %v want %v", - test.in, test.base, s, test.out) - } + x := AppendInt([]byte("abc"), test.in, test.base) + if string(x) != "abc"+test.out { + t.Errorf("AppendInt(%q, %v, %v) = %q want %v", + "abc", test.in, test.base, x, test.out) } - if int64(int(test.in)) == test.in { - s := Itob(int(test.in), test.base) + if test.in >= 0 { + s := FormatUint(uint64(test.in), test.base) if s != test.out { - t.Errorf("Itob(%v, %v) = %v want %v", + t.Errorf("FormatUint(%v, %v) = %v want %v", test.in, test.base, s, test.out) } - - if test.in >= 0 { - s := Uitob(uint(test.in), test.base) - if s != test.out { - t.Errorf("Uitob(%v, %v) = %v want %v", - test.in, test.base, s, test.out) - } + x := AppendUint(nil, uint64(test.in), test.base) + if string(x) != test.out { + t.Errorf("AppendUint(%q, %v, %v) = %q want %v", + "abc", uint64(test.in), test.base, x, test.out) } } - if test.base == 10 { - s := Itoa64(test.in) + if test.base == 10 && int64(int(test.in)) == test.in { + s := Itoa(int(test.in)) if s != test.out { - t.Errorf("Itoa64(%v) = %v want %v", + t.Errorf("Itoa(%v) = %v want %v", test.in, s, test.out) } - - if test.in >= 0 { - s := Uitob64(uint64(test.in), test.base) - if s != test.out { - t.Errorf("Uitob64(%v, %v) = %v want %v", - test.in, test.base, s, test.out) - } - } - - if int64(int(test.in)) == test.in { - s := Itoa(int(test.in)) - if s != test.out { - t.Errorf("Itoa(%v) = %v want %v", - test.in, s, test.out) - } - - if test.in >= 0 { - s := Uitoa(uint(test.in)) - if s != test.out { - t.Errorf("Uitoa(%v) = %v want %v", - test.in, s, test.out) - } - } - } } } } type uitob64Test struct { in uint64 - base uint + base int out string } @@ -141,34 +111,50 @@ var uitob64tests = []uitob64Test{ func TestUitoa(t *testing.T) { for _, test := range uitob64tests { - s := Uitob64(test.in, test.base) + s := FormatUint(test.in, test.base) if s != test.out { - t.Errorf("Uitob64(%v, %v) = %v want %v", + t.Errorf("FormatUint(%v, %v) = %v want %v", test.in, test.base, s, test.out) } + x := AppendUint([]byte("abc"), test.in, test.base) + if string(x) != "abc"+test.out { + t.Errorf("AppendUint(%q, %v, %v) = %q want %v", + "abc", test.in, test.base, x, test.out) + } - if uint64(uint(test.in)) == test.in { - s := Uitob(uint(test.in), test.base) - if s != test.out { - t.Errorf("Uitob(%v, %v) = %v want %v", - test.in, test.base, s, test.out) - } + } +} + +func BenchmarkFormatInt(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, test := range itob64tests { + FormatInt(test.in, test.base) } + } +} - if test.base == 10 { - s := Uitoa64(test.in) - if s != test.out { - t.Errorf("Uitoa64(%v) = %v want %v", - test.in, s, test.out) - } +func BenchmarkAppendInt(b *testing.B) { + dst := make([]byte, 0, 30) + for i := 0; i < b.N; i++ { + for _, test := range itob64tests { + AppendInt(dst, test.in, test.base) + } + } +} - if uint64(uint(test.in)) == test.in { - s := Uitoa(uint(test.in)) - if s != test.out { - t.Errorf("Uitoa(%v) = %v want %v", - test.in, s, test.out) - } - } +func BenchmarkFormatUint(b *testing.B) { + for i := 0; i < b.N; i++ { + for _, test := range uitob64tests { + FormatUint(test.in, test.base) + } + } +} + +func BenchmarkAppendUint(b *testing.B) { + dst := make([]byte, 0, 30) + for i := 0; i < b.N; i++ { + for _, test := range uitob64tests { + AppendUint(dst, test.in, test.base) } } } diff --git a/libgo/go/strconv/quote.go b/libgo/go/strconv/quote.go index 9b48c07fb1d..30b384df8e3 100644 --- a/libgo/go/strconv/quote.go +++ b/libgo/go/strconv/quote.go @@ -92,6 +92,12 @@ func Quote(s string) string { return quoteWith(s, '"', false) } +// AppendQuote appends a double-quoted Go string literal representing s, +// as generated by Quote, to dst and returns the extended buffer. +func AppendQuote(dst []byte, s string) []byte { + return append(dst, Quote(s)...) +} + // QuoteToASCII returns a double-quoted Go string literal representing s. // The returned string uses Go escape sequences (\t, \n, \xFF, \u0100) for // non-ASCII characters and non-printable characters as defined by @@ -100,6 +106,12 @@ func QuoteToASCII(s string) string { return quoteWith(s, '"', true) } +// AppendQuoteToASCII appends a double-quoted Go string literal representing s, +// as generated by QuoteToASCII, to dst and returns the extended buffer. +func AppendQuoteToASCII(dst []byte, s string) []byte { + return append(dst, QuoteToASCII(s)...) +} + // QuoteRune returns a single-quoted Go character literal representing the // rune. The returned string uses Go escape sequences (\t, \n, \xFF, \u0100) // for control characters and non-printable characters as defined by @@ -109,6 +121,12 @@ func QuoteRune(rune int) string { return quoteWith(string(rune), '\'', false) } +// AppendQuoteRune appends a single-quoted Go character literal representing the rune, +// as generated by QuoteRune, to dst and returns the extended buffer. +func AppendQuoteRune(dst []byte, rune int) []byte { + return append(dst, QuoteRune(rune)...) +} + // QuoteRuneToASCII returns a single-quoted Go character literal representing // the rune. The returned string uses Go escape sequences (\t, \n, \xFF, // \u0100) for non-ASCII characters and non-printable characters as defined @@ -118,6 +136,12 @@ func QuoteRuneToASCII(rune int) string { return quoteWith(string(rune), '\'', true) } +// AppendQuoteRune appends a single-quoted Go character literal representing the rune, +// as generated by QuoteRuneToASCII, to dst and returns the extended buffer. +func AppendQuoteRuneToASCII(dst []byte, rune int) []byte { + return append(dst, QuoteRuneToASCII(rune)...) +} + // CanBackquote returns whether the string s would be // a valid Go string literal if enclosed in backquotes. func CanBackquote(s string) bool { diff --git a/libgo/go/strconv/quote_test.go b/libgo/go/strconv/quote_test.go index 9a597700d27..e440797162b 100644 --- a/libgo/go/strconv/quote_test.go +++ b/libgo/go/strconv/quote_test.go @@ -29,6 +29,9 @@ func TestQuote(t *testing.T) { if out := Quote(tt.in); out != tt.out { t.Errorf("Quote(%s) = %s, want %s", tt.in, out, tt.out) } + if out := AppendQuote([]byte("abc"), tt.in); string(out) != "abc"+tt.out { + t.Errorf("AppendQuote(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.out) + } } } @@ -37,6 +40,9 @@ func TestQuoteToASCII(t *testing.T) { if out := QuoteToASCII(tt.in); out != tt.ascii { t.Errorf("QuoteToASCII(%s) = %s, want %s", tt.in, out, tt.ascii) } + if out := AppendQuoteToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii { + t.Errorf("AppendQuoteToASCII(%q, %s) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii) + } } } @@ -63,6 +69,9 @@ func TestQuoteRune(t *testing.T) { if out := QuoteRune(tt.in); out != tt.out { t.Errorf("QuoteRune(%U) = %s, want %s", tt.in, out, tt.out) } + if out := AppendQuoteRune([]byte("abc"), tt.in); string(out) != "abc"+tt.out { + t.Errorf("AppendQuoteRune(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.out) + } } } @@ -71,6 +80,9 @@ func TestQuoteRuneToASCII(t *testing.T) { if out := QuoteRuneToASCII(tt.in); out != tt.ascii { t.Errorf("QuoteRuneToASCII(%U) = %s, want %s", tt.in, out, tt.ascii) } + if out := AppendQuoteRuneToASCII([]byte("abc"), tt.in); string(out) != "abc"+tt.ascii { + t.Errorf("AppendQuoteRuneToASCII(%q, %U) = %s, want %s", "abc", tt.in, out, "abc"+tt.ascii) + } } } diff --git a/libgo/go/text/template/multi_test.go b/libgo/go/text/template/multi_test.go index 7b35d2633d5..3abb51f3383 100644 --- a/libgo/go/text/template/multi_test.go +++ b/libgo/go/text/template/multi_test.go @@ -13,35 +13,6 @@ import ( "text/template/parse" ) -type isEmptyTest struct { - name string - input string - empty bool -} - -var isEmptyTests = []isEmptyTest{ - {"empty", ``, true}, - {"nonempty", `hello`, false}, - {"spaces only", " \t\n \t\n", true}, - {"definition", `{{define "x"}}something{{end}}`, true}, - {"definitions and space", "{{define `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true}, - {"definitions and text", "{{define `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n}}", false}, - {"definition and action", "{{define `x`}}something{{end}}{{if 3}}foo{{end}}", false}, -} - -func TestIsEmpty(t *testing.T) { - for _, test := range isEmptyTests { - template, err := New("root").Parse(test.input) - if err != nil { - t.Errorf("%q: unexpected error: %v", test.name, err) - continue - } - if empty := isEmpty(template.Root); empty != test.empty { - t.Errorf("%q: expected %t got %t", test.name, test.empty, empty) - } - } -} - const ( noError = true hasError = false diff --git a/libgo/go/text/template/parse/node.go b/libgo/go/text/template/parse/node.go index a4e5514768a..4f43424239a 100644 --- a/libgo/go/text/template/parse/node.go +++ b/libgo/go/text/template/parse/node.go @@ -267,7 +267,7 @@ func newNumber(text string, typ itemType) (*NumberNode, error) { } // Imaginary constants can only be complex unless they are zero. if len(text) > 0 && text[len(text)-1] == 'i' { - f, err := strconv.Atof64(text[:len(text)-1]) + f, err := strconv.ParseFloat(text[:len(text)-1], 64) if err == nil { n.IsComplex = true n.Complex128 = complex(0, f) @@ -276,12 +276,12 @@ func newNumber(text string, typ itemType) (*NumberNode, error) { } } // Do integer test first so we get 0x123 etc. - u, err := strconv.Btoui64(text, 0) // will fail for -0; fixed below. + u, err := strconv.ParseUint(text, 0, 64) // will fail for -0; fixed below. if err == nil { n.IsUint = true n.Uint64 = u } - i, err := strconv.Btoi64(text, 0) + i, err := strconv.ParseInt(text, 0, 64) if err == nil { n.IsInt = true n.Int64 = i @@ -298,7 +298,7 @@ func newNumber(text string, typ itemType) (*NumberNode, error) { n.IsFloat = true n.Float64 = float64(n.Uint64) } else { - f, err := strconv.Atof64(text) + f, err := strconv.ParseFloat(text, 64) if err == nil { n.IsFloat = true n.Float64 = f diff --git a/libgo/go/text/template/parse/parse.go b/libgo/go/text/template/parse/parse.go index 346f613b048..4da756657d5 100644 --- a/libgo/go/text/template/parse/parse.go +++ b/libgo/go/text/template/parse/parse.go @@ -7,6 +7,7 @@ package parse import ( + "bytes" "fmt" "runtime" "strconv" @@ -177,10 +178,37 @@ func (t *Tree) Parse(s, leftDelim, rightDelim string, treeSet map[string]*Tree, // add adds tree to the treeSet. func (t *Tree) add(treeSet map[string]*Tree) { - if _, present := treeSet[t.Name]; present { + tree := treeSet[t.Name] + if tree == nil || IsEmptyTree(tree.Root) { + treeSet[t.Name] = t + return + } + if !IsEmptyTree(t.Root) { t.errorf("template: multiple definition of template %q", t.Name) } - treeSet[t.Name] = t +} + +// IsEmptyTree reports whether this tree (node) is empty of everything but space. +func IsEmptyTree(n Node) bool { + switch n := n.(type) { + case *ActionNode: + case *IfNode: + case *ListNode: + for _, node := range n.Nodes { + if !IsEmptyTree(node) { + return false + } + } + return true + case *RangeNode: + case *TemplateNode: + case *TextNode: + return len(bytes.TrimSpace(n.Text)) == 0 + case *WithNode: + default: + panic("unknown node: " + n.String()) + } + return false } // parse is the top-level parser for a template, essentially the same diff --git a/libgo/go/text/template/parse/parse_test.go b/libgo/go/text/template/parse/parse_test.go index fc93455ecbc..b70c2143d3d 100644 --- a/libgo/go/text/template/parse/parse_test.go +++ b/libgo/go/text/template/parse/parse_test.go @@ -257,3 +257,32 @@ func TestParse(t *testing.T) { } } } + +type isEmptyTest struct { + name string + input string + empty bool +} + +var isEmptyTests = []isEmptyTest{ + {"empty", ``, true}, + {"nonempty", `hello`, false}, + {"spaces only", " \t\n \t\n", true}, + {"definition", `{{define "x"}}something{{end}}`, true}, + {"definitions and space", "{{define `x`}}something{{end}}\n\n{{define `y`}}something{{end}}\n\n", true}, + {"definitions and text", "{{define `x`}}something{{end}}\nx\n{{define `y`}}something{{end}}\ny\n}}", false}, + {"definition and action", "{{define `x`}}something{{end}}{{if 3}}foo{{end}}", false}, +} + +func TestIsEmpty(t *testing.T) { + for _, test := range isEmptyTests { + tree, err := New("root").Parse(test.input, "", "", make(map[string]*Tree), nil) + if err != nil { + t.Errorf("%q: unexpected error: %v", test.name, err) + continue + } + if empty := IsEmptyTree(tree.Root); empty != test.empty { + t.Errorf("%q: expected %t got %t", test.name, test.empty, empty) + } + } +} diff --git a/libgo/go/text/template/template.go b/libgo/go/text/template/template.go index 04fca407c10..cbc68081748 100644 --- a/libgo/go/text/template/template.go +++ b/libgo/go/text/template/template.go @@ -5,7 +5,6 @@ package template import ( - "bytes" "fmt" "reflect" "text/template/parse" @@ -198,8 +197,8 @@ func (t *Template) associate(new *Template) error { } name := new.name if old := t.tmpl[name]; old != nil { - oldIsEmpty := isEmpty(old.Root) - newIsEmpty := isEmpty(new.Root) + oldIsEmpty := parse.IsEmptyTree(old.Root) + newIsEmpty := parse.IsEmptyTree(new.Root) if !oldIsEmpty && !newIsEmpty { return fmt.Errorf("template: redefinition of template %q", name) } @@ -211,26 +210,3 @@ func (t *Template) associate(new *Template) error { t.tmpl[name] = new return nil } - -// isEmpty reports whether this tree (node) is empty of everything but space. -func isEmpty(n parse.Node) bool { - switch n := n.(type) { - case *parse.ActionNode: - case *parse.IfNode: - case *parse.ListNode: - for _, node := range n.Nodes { - if !isEmpty(node) { - return false - } - } - return true - case *parse.RangeNode: - case *parse.TemplateNode: - case *parse.TextNode: - return len(bytes.TrimSpace(n.Text)) == 0 - case *parse.WithNode: - default: - panic("unknown node: " + n.String()) - } - return false -} diff --git a/libgo/go/time/time_test.go b/libgo/go/time/time_test.go index 9590e281a66..6d1e79b542b 100644 --- a/libgo/go/time/time_test.go +++ b/libgo/go/time/time_test.go @@ -339,7 +339,7 @@ func checkTime(time Time, test *ParseTest, t *testing.T) { t.Errorf("%s: bad second: %d not %d", test.name, time.Second(), 57) } // Nanoseconds must be checked against the precision of the input. - nanosec, err := strconv.Atoui("012345678"[:test.fracDigits] + "000000000"[:9-test.fracDigits]) + nanosec, err := strconv.ParseUint("012345678"[:test.fracDigits]+"000000000"[:9-test.fracDigits], 10, 0) if err != nil { panic(err) } diff --git a/libgo/go/unicode/graphic.go b/libgo/go/unicode/graphic.go index 9343bc9b0a9..2904da6c6d9 100644 --- a/libgo/go/unicode/graphic.go +++ b/libgo/go/unicode/graphic.go @@ -32,8 +32,8 @@ var PrintRanges = []*RangeTable{ // Such characters include letters, marks, numbers, punctuation, symbols, and // spaces, from categories L, M, N, P, S, Zs. func IsGraphic(r rune) bool { - // We cast to uint32 to avoid the extra test for negative, - // and in the index we cast to uint8 to avoid the range check. + // We convert to uint32 to avoid the extra test for negative, + // and in the index we convert to uint8 to avoid the range check. if uint32(r) <= MaxLatin1 { return properties[uint8(r)]&pg != 0 } diff --git a/libgo/go/websocket/hixie.go b/libgo/go/websocket/hixie.go index ec7b7ae0a45..d0ddbeeb484 100644 --- a/libgo/go/websocket/hixie.go +++ b/libgo/go/websocket/hixie.go @@ -365,13 +365,13 @@ func hixie76ClientHandshake(config *Config, br *bufio.Reader, bw *bufio.Writer) key2, number2 := generateKeyNumber() if config.handshakeData != nil { key1 = config.handshakeData["key1"] - n, err := strconv.Atoui(config.handshakeData["number1"]) + n, err := strconv.ParseUint(config.handshakeData["number1"], 10, 32) if err != nil { panic(err) } number1 = uint32(n) key2 = config.handshakeData["key2"] - n, err = strconv.Atoui(config.handshakeData["number2"]) + n, err = strconv.ParseUint(config.handshakeData["number2"], 10, 32) if err != nil { panic(err) } |