From 501699af1603287b1b47ac450fd6eeb826aa76b1 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 2 Mar 2012 20:01:37 +0000 Subject: libgo: Update to weekly.2012-02-22 release. From-SVN: r184819 --- libgo/MERGE | 2 +- libgo/Makefile.am | 9 +- libgo/Makefile.in | 9 +- libgo/go/bufio/bufio.go | 9 +- libgo/go/bufio/bufio_test.go | 21 + libgo/go/bytes/bytes.go | 2 + libgo/go/bytes/bytes_test.go | 41 +- libgo/go/bytes/example_test.go | 4 +- libgo/go/compress/flate/deflate_test.go | 7 + libgo/go/container/heap/example_test.go | 42 +- libgo/go/crypto/dsa/dsa.go | 2 +- libgo/go/crypto/md5/md5_test.go | 13 +- libgo/go/crypto/sha1/sha1_test.go | 12 +- libgo/go/crypto/tls/handshake_client.go | 4 +- libgo/go/crypto/tls/handshake_server.go | 4 +- libgo/go/database/sql/convert.go | 4 +- libgo/go/database/sql/driver/driver.go | 51 ++- libgo/go/database/sql/driver/types.go | 80 ++-- libgo/go/database/sql/fakedb_test.go | 16 +- libgo/go/database/sql/sql.go | 54 +-- libgo/go/debug/dwarf/open.go | 5 +- libgo/go/debug/dwarf/testdata/typedef.c | 8 +- libgo/go/debug/dwarf/testdata/typedef.elf | Bin 10837 -> 12448 bytes libgo/go/debug/dwarf/testdata/typedef.macho | Bin 5256 -> 5024 bytes libgo/go/debug/dwarf/type.go | 36 +- libgo/go/debug/dwarf/type_test.go | 19 +- libgo/go/debug/gosym/pclntab_test.go | 35 +- libgo/go/encoding/gob/decode.go | 14 +- libgo/go/encoding/gob/encoder_test.go | 51 +++ libgo/go/encoding/gob/type.go | 16 + libgo/go/encoding/json/decode.go | 14 + libgo/go/encoding/json/decode_test.go | 29 ++ libgo/go/encoding/json/encode.go | 5 + libgo/go/encoding/xml/marshal.go | 89 +++-- libgo/go/encoding/xml/read.go | 55 +-- libgo/go/errors/errors_test.go | 30 +- libgo/go/exp/inotify/inotify_linux_test.go | 20 +- libgo/go/exp/norm/composition.go | 85 +++- libgo/go/exp/norm/composition_test.go | 32 +- libgo/go/exp/norm/input.go | 10 +- libgo/go/exp/norm/iter.go | 286 ++++++++++++++ libgo/go/exp/norm/iter_test.go | 186 +++++++++ libgo/go/exp/norm/normalize.go | 15 +- libgo/go/exp/norm/normalize_test.go | 55 ++- libgo/go/exp/norm/normregtest.go | 11 + libgo/go/exp/proxy/socks5.go | 6 +- libgo/go/exp/terminal/terminal.go | 4 +- libgo/go/exp/winfsnotify/winfsnotify_test.go | 9 +- libgo/go/go/doc/example.go | 65 ++- libgo/go/go/doc/reader.go | 10 +- libgo/go/go/doc/synopsis.go | 52 +++ libgo/go/go/doc/synopsis_test.go | 44 +++ libgo/go/go/doc/testdata/benchmark.go | 6 +- libgo/go/go/doc/testdata/testing.1.golden | 2 +- libgo/go/go/doc/testdata/testing.go | 10 +- libgo/go/go/parser/parser.go | 261 +++++++----- libgo/go/go/printer/nodes.go | 106 ++--- libgo/go/go/printer/printer.go | 8 +- libgo/go/go/printer/printer_test.go | 8 +- libgo/go/go/printer/testdata/comments.golden | 43 +- libgo/go/go/printer/testdata/comments.input | 31 +- libgo/go/go/printer/testdata/expressions.golden | 6 +- libgo/go/go/printer/testdata/expressions.raw | 6 +- libgo/go/go/scanner/scanner.go | 18 +- libgo/go/html/template/clone.go | 90 ----- libgo/go/html/template/clone_test.go | 175 ++++---- libgo/go/html/template/content.go | 18 +- libgo/go/html/template/content_test.go | 40 ++ libgo/go/html/template/doc.go | 12 +- libgo/go/html/template/escape.go | 94 ++--- libgo/go/html/template/template.go | 73 +++- libgo/go/image/decode_example_test.go | 79 ++++ libgo/go/image/ycbcr_test.go | 3 + libgo/go/io/ioutil/tempfile.go | 4 +- libgo/go/log/syslog/syslog.go | 2 + libgo/go/log/syslog/syslog_test.go | 3 + libgo/go/log/syslog/syslog_unix.go | 2 + libgo/go/math/big/nat_test.go | 3 + libgo/go/math/rand/rand.go | 13 +- libgo/go/math/rand/rand_test.go | 6 + libgo/go/net/dialgoogle_test.go | 4 +- libgo/go/net/fd.go | 6 +- libgo/go/net/fd_windows.go | 20 +- libgo/go/net/file.go | 8 +- libgo/go/net/file_plan9.go | 7 +- libgo/go/net/hosts_test.go | 2 +- libgo/go/net/http/cookie_test.go | 28 ++ libgo/go/net/http/example_test.go | 51 +++ libgo/go/net/http/fs_test.go | 13 +- libgo/go/net/http/httputil/persist.go | 4 +- libgo/go/net/http/pprof/pprof.go | 81 +++- libgo/go/net/http/request.go | 4 +- libgo/go/net/http/serve_test.go | 5 +- libgo/go/net/http/server.go | 11 +- libgo/go/net/http/transport_test.go | 6 +- libgo/go/net/interface_linux.go | 30 +- libgo/go/net/interface_test.go | 8 +- libgo/go/net/ipraw_test.go | 62 +-- libgo/go/net/iprawsock_plan9.go | 26 +- libgo/go/net/iprawsock_posix.go | 24 +- libgo/go/net/ipsock_plan9.go | 15 +- libgo/go/net/ipsock_posix.go | 11 +- libgo/go/net/lookup_plan9.go | 3 +- libgo/go/net/lookup_test.go | 12 +- libgo/go/net/multicast_test.go | 181 +++++---- libgo/go/net/net.go | 60 ++- libgo/go/net/parse.go | 2 +- libgo/go/net/rpc/server_test.go | 4 +- libgo/go/net/server_test.go | 2 +- libgo/go/net/smtp/smtp.go | 7 +- libgo/go/net/smtp/smtp_test.go | 95 ++++- libgo/go/net/sock.go | 12 +- libgo/go/net/tcpsock_plan9.go | 16 +- libgo/go/net/tcpsock_posix.go | 49 ++- libgo/go/net/testdata/hosts | 12 + libgo/go/net/testdata/igmp | 24 ++ libgo/go/net/testdata/igmp6 | 18 + libgo/go/net/textproto/reader.go | 13 +- libgo/go/net/textproto/reader_test.go | 23 ++ libgo/go/net/textproto/textproto.go | 3 + libgo/go/net/udpsock_plan9.go | 19 +- libgo/go/net/udpsock_posix.go | 28 +- libgo/go/net/unixsock_plan9.go | 26 +- libgo/go/net/unixsock_posix.go | 46 +-- libgo/go/net/url/url.go | 51 ++- libgo/go/net/url/url_test.go | 35 +- libgo/go/old/netchan/netchan_test.go | 12 + libgo/go/os/dir_plan9.go | 11 +- libgo/go/os/env.go | 23 +- libgo/go/os/error.go | 12 + libgo/go/os/error_plan9.go | 60 +-- libgo/go/os/error_posix.go | 67 ++-- libgo/go/os/exec/exec.go | 16 +- libgo/go/os/exec/lp_plan9.go | 3 +- libgo/go/os/exec/lp_unix.go | 2 +- libgo/go/os/exec/lp_windows.go | 4 +- libgo/go/os/exec_plan9.go | 97 +++-- libgo/go/os/exec_posix.go | 83 ++-- libgo/go/os/exec_unix.go | 52 ++- libgo/go/os/exec_windows.go | 21 +- libgo/go/os/file.go | 49 ++- libgo/go/os/file_plan9.go | 42 +- libgo/go/os/file_posix.go | 17 +- libgo/go/os/file_unix.go | 2 +- libgo/go/os/getwd.go | 4 +- libgo/go/os/os_test.go | 36 +- libgo/go/os/path.go | 9 +- libgo/go/os/path_test.go | 32 +- libgo/go/os/signal/signal_stub.go | 11 + libgo/go/os/stat_plan9.go | 4 +- libgo/go/path/example_test.go | 26 +- libgo/go/path/filepath/match.go | 6 +- libgo/go/path/filepath/path.go | 19 +- libgo/go/path/filepath/path_test.go | 5 + libgo/go/path/match.go | 4 +- libgo/go/path/path.go | 21 +- libgo/go/runtime/debug.go | 51 +-- libgo/go/runtime/extern.go | 15 +- libgo/go/runtime/malloc1.go | 26 ++ libgo/go/runtime/mallocrand.go | 93 +++++ libgo/go/runtime/mallocrep.go | 72 ++++ libgo/go/runtime/mallocrep1.go | 143 +++++++ libgo/go/runtime/mem.go | 14 +- libgo/go/runtime/pprof/pprof.go | 504 +++++++++++++++++++++--- libgo/go/runtime/sema_test.go | 100 ----- libgo/go/sort/example_interface_test.go | 77 ++++ libgo/go/sort/example_reverse_test.go | 30 ++ libgo/go/sort/example_test.go | 2 +- libgo/go/strconv/atof.go | 6 + libgo/go/strconv/itoa_test.go | 1 + libgo/go/strings/example_test.go | 93 +++-- libgo/go/sync/cond.go | 15 +- libgo/go/sync/example_test.go | 34 ++ libgo/go/sync/export_test.go | 9 + libgo/go/sync/mutex.go | 9 +- libgo/go/sync/mutex_test.go | 4 +- libgo/go/sync/runtime.go | 18 + libgo/go/sync/runtime_sema_test.go | 101 +++++ libgo/go/sync/rwmutex.go | 13 +- libgo/go/sync/waitgroup.go | 9 +- libgo/go/testing/testing.go | 19 +- libgo/go/text/tabwriter/example_test.go | 38 ++ libgo/go/text/tabwriter/tabwriter.go | 6 - libgo/go/text/tabwriter/tabwriter_test.go | 3 +- libgo/go/text/template/doc.go | 24 +- libgo/go/text/template/exec.go | 10 +- libgo/go/text/template/exec_test.go | 8 + libgo/go/text/template/multi_test.go | 2 +- libgo/go/text/template/parse/parse.go | 6 +- libgo/go/text/template/template.go | 8 +- libgo/go/time/example_test.go | 2 +- libgo/go/time/sys_plan9.go | 38 +- libgo/go/time/sys_unix.go | 38 +- libgo/go/time/sys_windows.go | 64 +++ libgo/go/time/tick_test.go | 3 - libgo/go/time/zoneinfo.go | 23 +- libgo/go/time/zoneinfo_plan9.go | 27 +- libgo/go/time/zoneinfo_read.go | 341 ++++++++++++++++ libgo/go/time/zoneinfo_unix.go | 197 +-------- libgo/go/time/zoneinfo_windows.go | 6 +- libgo/runtime/malloc.goc | 13 +- libgo/runtime/malloc.h | 19 +- libgo/runtime/mgc0.c | 44 ++- libgo/runtime/mheap.c | 88 ++++- libgo/runtime/mprof.goc | 129 +++++- libgo/runtime/proc.c | 29 +- libgo/runtime/runtime.h | 18 +- libgo/runtime/sema.goc | 6 +- libgo/runtime/sigqueue.goc | 2 + 209 files changed, 5285 insertions(+), 2086 deletions(-) create mode 100644 libgo/go/exp/norm/iter.go create mode 100644 libgo/go/exp/norm/iter_test.go create mode 100644 libgo/go/go/doc/synopsis.go create mode 100644 libgo/go/go/doc/synopsis_test.go delete mode 100644 libgo/go/html/template/clone.go create mode 100644 libgo/go/image/decode_example_test.go create mode 100644 libgo/go/net/http/example_test.go create mode 100644 libgo/go/net/testdata/hosts create mode 100644 libgo/go/net/testdata/igmp create mode 100644 libgo/go/net/testdata/igmp6 create mode 100644 libgo/go/os/signal/signal_stub.go create mode 100644 libgo/go/runtime/malloc1.go create mode 100644 libgo/go/runtime/mallocrand.go create mode 100644 libgo/go/runtime/mallocrep.go create mode 100644 libgo/go/runtime/mallocrep1.go delete mode 100644 libgo/go/runtime/sema_test.go create mode 100644 libgo/go/sort/example_interface_test.go create mode 100644 libgo/go/sort/example_reverse_test.go create mode 100644 libgo/go/sync/example_test.go create mode 100644 libgo/go/sync/export_test.go create mode 100644 libgo/go/sync/runtime.go create mode 100644 libgo/go/sync/runtime_sema_test.go create mode 100644 libgo/go/text/tabwriter/example_test.go create mode 100644 libgo/go/time/zoneinfo_read.go (limited to 'libgo') diff --git a/libgo/MERGE b/libgo/MERGE index a760ae9..9605a8a 100644 --- a/libgo/MERGE +++ b/libgo/MERGE @@ -1,4 +1,4 @@ -43cf9b39b647 +96bd78e7d35e 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/Makefile.am b/libgo/Makefile.am index 1167a3f..eb764df 100644 --- a/libgo/Makefile.am +++ b/libgo/Makefile.am @@ -504,7 +504,7 @@ runtime1.c: $(srcdir)/runtime/runtime1.goc goc2c mv -f $@.tmp $@ sema.c: $(srcdir)/runtime/sema.goc goc2c - ./goc2c --gcc --go-prefix libgo_runtime $< > $@.tmp + ./goc2c --gcc --go-prefix libgo_sync $< > $@.tmp mv -f $@.tmp $@ sigqueue.c: $(srcdir)/runtime/sigqueue.goc goc2c @@ -847,6 +847,7 @@ go_sync_files = \ go/sync/cond.go \ go/sync/mutex.go \ go/sync/once.go \ + go/sync/runtime.go \ go/sync/rwmutex.go \ go/sync/waitgroup.go @@ -878,6 +879,7 @@ go_time_files = \ go/time/tick.go \ go/time/time.go \ go/time/zoneinfo.go \ + go/time/zoneinfo_read.go \ go/time/zoneinfo_unix.go go_unicode_files = \ @@ -1091,6 +1093,7 @@ go_exp_norm_files = \ go/exp/norm/composition.go \ go/exp/norm/forminfo.go \ go/exp/norm/input.go \ + go/exp/norm/iter.go \ go/exp/norm/normalize.go \ go/exp/norm/readwriter.go \ go/exp/norm/tables.go \ @@ -1132,7 +1135,8 @@ go_go_doc_files = \ go/go/doc/example.go \ go/go/doc/exports.go \ go/go/doc/filter.go \ - go/go/doc/reader.go + go/go/doc/reader.go \ + go/go/doc/synopsis.go go_go_parser_files = \ go/go/parser/interface.go \ go/go/parser/parser.go @@ -1159,7 +1163,6 @@ go_hash_fnv_files = \ go_html_template_files = \ go/html/template/attr.go \ - go/html/template/clone.go \ go/html/template/content.go \ go/html/template/context.go \ go/html/template/css.go \ diff --git a/libgo/Makefile.in b/libgo/Makefile.in index b1d1d4c..4604e56 100644 --- a/libgo/Makefile.in +++ b/libgo/Makefile.in @@ -1157,6 +1157,7 @@ go_sync_files = \ go/sync/cond.go \ go/sync/mutex.go \ go/sync/once.go \ + go/sync/runtime.go \ go/sync/rwmutex.go \ go/sync/waitgroup.go @@ -1182,6 +1183,7 @@ go_time_files = \ go/time/tick.go \ go/time/time.go \ go/time/zoneinfo.go \ + go/time/zoneinfo_read.go \ go/time/zoneinfo_unix.go go_unicode_files = \ @@ -1427,6 +1429,7 @@ go_exp_norm_files = \ go/exp/norm/composition.go \ go/exp/norm/forminfo.go \ go/exp/norm/input.go \ + go/exp/norm/iter.go \ go/exp/norm/normalize.go \ go/exp/norm/readwriter.go \ go/exp/norm/tables.go \ @@ -1474,7 +1477,8 @@ go_go_doc_files = \ go/go/doc/example.go \ go/go/doc/exports.go \ go/go/doc/filter.go \ - go/go/doc/reader.go + go/go/doc/reader.go \ + go/go/doc/synopsis.go go_go_parser_files = \ go/go/parser/interface.go \ @@ -1508,7 +1512,6 @@ go_hash_fnv_files = \ go_html_template_files = \ go/html/template/attr.go \ - go/html/template/clone.go \ go/html/template/content.go \ go/html/template/context.go \ go/html/template/css.go \ @@ -4318,7 +4321,7 @@ runtime1.c: $(srcdir)/runtime/runtime1.goc goc2c mv -f $@.tmp $@ sema.c: $(srcdir)/runtime/sema.goc goc2c - ./goc2c --gcc --go-prefix libgo_runtime $< > $@.tmp + ./goc2c --gcc --go-prefix libgo_sync $< > $@.tmp mv -f $@.tmp $@ sigqueue.c: $(srcdir)/runtime/sigqueue.goc goc2c diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go index 156dddf..6f3b1ee 100644 --- a/libgo/go/bufio/bufio.go +++ b/libgo/go/bufio/bufio.go @@ -106,9 +106,12 @@ func (b *Reader) Peek(n int) ([]byte, error) { if m > n { m = n } - err := b.readErr() - if m < n && err == nil { - err = ErrBufferFull + var err error + if m < n { + err = b.readErr() + if err == nil { + err = ErrBufferFull + } } return b.buf[b.r : b.r+m], err } diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go index 9aec61e..a43cbd2 100644 --- a/libgo/go/bufio/bufio_test.go +++ b/libgo/go/bufio/bufio_test.go @@ -539,6 +539,27 @@ func TestPeek(t *testing.T) { if _, err := buf.Peek(1); err != io.EOF { t.Fatalf("want EOF got %v", err) } + + // Test for issue 3022, not exposing a reader's error on a successful Peek. + buf = NewReaderSize(dataAndEOFReader("abcd"), 32) + if s, err := buf.Peek(2); string(s) != "ab" || err != nil { + t.Errorf(`Peek(2) on "abcd", EOF = %q, %v; want "ab", nil`, string(s), err) + } + if s, err := buf.Peek(4); string(s) != "abcd" || err != nil { + t.Errorf(`Peek(4) on "abcd", EOF = %q, %v; want "abcd", nil`, string(s), err) + } + if n, err := buf.Read(p[0:5]); string(p[0:n]) != "abcd" || err != nil { + t.Fatalf("Read after peek = %q, %v; want abcd, EOF", p[0:n], err) + } + if n, err := buf.Read(p[0:1]); string(p[0:n]) != "" || err != io.EOF { + t.Fatalf(`second Read after peek = %q, %v; want "", EOF`, p[0:n], err) + } +} + +type dataAndEOFReader string + +func (r dataAndEOFReader) Read(p []byte) (int, error) { + return copy(p, r), io.EOF } func TestPeekThenUnreadRune(t *testing.T) { diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go index e94a0ec..7d1426f 100644 --- a/libgo/go/bytes/bytes.go +++ b/libgo/go/bytes/bytes.go @@ -13,6 +13,7 @@ import ( // Compare returns an integer comparing the two byte arrays lexicographically. // The result will be 0 if a==b, -1 if a < b, and +1 if a > b +// A nil argument is equivalent to an empty slice. func Compare(a, b []byte) int { m := len(a) if m > len(b) { @@ -37,6 +38,7 @@ func Compare(a, b []byte) int { } // Equal returns a boolean reporting whether a == b. +// A nil argument is equivalent to an empty slice. func Equal(a, b []byte) bool func equalPortable(a, b []byte) bool { diff --git a/libgo/go/bytes/bytes_test.go b/libgo/go/bytes/bytes_test.go index 2a1d41b..000f235 100644 --- a/libgo/go/bytes/bytes_test.go +++ b/libgo/go/bytes/bytes_test.go @@ -46,32 +46,39 @@ type BinOpTest struct { i int } -var comparetests = []BinOpTest{ - {"", "", 0}, - {"a", "", 1}, - {"", "a", -1}, - {"abc", "abc", 0}, - {"ab", "abc", -1}, - {"abc", "ab", 1}, - {"x", "ab", 1}, - {"ab", "x", -1}, - {"x", "a", 1}, - {"b", "x", -1}, +var compareTests = []struct { + a, b []byte + i int +}{ + {[]byte(""), []byte(""), 0}, + {[]byte("a"), []byte(""), 1}, + {[]byte(""), []byte("a"), -1}, + {[]byte("abc"), []byte("abc"), 0}, + {[]byte("ab"), []byte("abc"), -1}, + {[]byte("abc"), []byte("ab"), 1}, + {[]byte("x"), []byte("ab"), 1}, + {[]byte("ab"), []byte("x"), -1}, + {[]byte("x"), []byte("a"), 1}, + {[]byte("b"), []byte("x"), -1}, + // nil tests + {nil, nil, 0}, + {[]byte(""), nil, 0}, + {nil, []byte(""), 0}, + {[]byte("a"), nil, 1}, + {nil, []byte("a"), -1}, } func TestCompare(t *testing.T) { - for _, tt := range comparetests { - a := []byte(tt.a) - b := []byte(tt.b) - cmp := Compare(a, b) + for _, tt := range compareTests { + cmp := Compare(tt.a, tt.b) if cmp != tt.i { t.Errorf(`Compare(%q, %q) = %v`, tt.a, tt.b, cmp) } - eql := Equal(a, b) + eql := Equal(tt.a, tt.b) if eql != (tt.i == 0) { t.Errorf(`Equal(%q, %q) = %v`, tt.a, tt.b, eql) } - eql = EqualPortable(a, b) + eql = EqualPortable(tt.a, tt.b) if eql != (tt.i == 0) { t.Errorf(`EqualPortable(%q, %q) = %v`, tt.a, tt.b, eql) } diff --git a/libgo/go/bytes/example_test.go b/libgo/go/bytes/example_test.go index 0234a01..6fe8cd5 100644 --- a/libgo/go/bytes/example_test.go +++ b/libgo/go/bytes/example_test.go @@ -11,18 +11,18 @@ import ( "os" ) -// Hello world! func ExampleBuffer() { var b Buffer // A Buffer needs no initialization. b.Write([]byte("Hello ")) b.Write([]byte("world!")) b.WriteTo(os.Stdout) + // Output: Hello world! } -// Gophers rule! func ExampleBuffer_reader() { // A Buffer can turn a string or a []byte into an io.Reader. buf := NewBufferString("R29waGVycyBydWxlIQ==") dec := base64.NewDecoder(base64.StdEncoding, buf) io.Copy(os.Stdout, dec) + // Output: Gophers rule! } diff --git a/libgo/go/compress/flate/deflate_test.go b/libgo/go/compress/flate/deflate_test.go index a76e2d9..543c595 100644 --- a/libgo/go/compress/flate/deflate_test.go +++ b/libgo/go/compress/flate/deflate_test.go @@ -306,6 +306,9 @@ func TestDeflateInflateString(t *testing.T) { t.Error(err) } testToFromWithLimit(t, gold, test.label, test.limit) + if testing.Short() { + break + } } } @@ -363,6 +366,10 @@ func TestWriterDict(t *testing.T) { // See http://code.google.com/p/go/issues/detail?id=2508 func TestRegression2508(t *testing.T) { + if testing.Short() { + t.Logf("test disabled with -short") + return + } w, err := NewWriter(ioutil.Discard, 1) if err != nil { t.Fatalf("NewWriter: %v", err) diff --git a/libgo/go/container/heap/example_test.go b/libgo/go/container/heap/example_test.go index c3b8d94..2050bc8 100644 --- a/libgo/go/container/heap/example_test.go +++ b/libgo/go/container/heap/example_test.go @@ -57,11 +57,26 @@ func (pq *PriorityQueue) Pop() interface{} { return item } -// 99:seven 88:five 77:zero 66:nine 55:three 44:two 33:six 22:one 11:four 00:eight -func ExampleInterface() { - // The full code of this example, including the methods that implement - // heap.Interface, is in the file src/pkg/container/heap/example_test.go. +// update is not used by the example but shows how to take the top item from +// the queue, update its priority and value, and put it back. +func (pq *PriorityQueue) update(value string, priority int) { + item := heap.Pop(pq).(*Item) + item.value = value + item.priority = priority + heap.Push(pq, item) +} +// changePriority is not used by the example but shows how to change the +// priority of an arbitrary item. +func (pq *PriorityQueue) changePriority(item *Item, priority int) { + heap.Remove(pq, item.index) + item.priority = priority + heap.Push(pq, item) +} + +// This example pushes 10 items into a PriorityQueue and takes them out in +// order of priority. +func Example() { const nItem = 10 // Random priorities for the items (a permutation of 0..9, times 11)). priorities := [nItem]int{ @@ -85,21 +100,6 @@ func ExampleInterface() { item := heap.Pop(&pq).(*Item) fmt.Printf("%.2d:%s ", item.priority, item.value) } -} - -// update is not used by the example but shows how to take the top item from the queue, -// update its priority and value, and put it back. -func (pq *PriorityQueue) update(value string, priority int) { - item := heap.Pop(pq).(*Item) - item.value = value - item.priority = priority - heap.Push(pq, item) -} - -// changePriority is not used by the example but shows how to change the priority of an arbitrary -// item. -func (pq *PriorityQueue) changePriority(item *Item, priority int) { - heap.Remove(pq, item.index) - item.priority = priority - heap.Push(pq, item) + // Output: + // 99:seven 88:five 77:zero 66:nine 55:three 44:two 33:six 22:one 11:four 00:eight } diff --git a/libgo/go/crypto/dsa/dsa.go b/libgo/go/crypto/dsa/dsa.go index f7c4783..05766a2 100644 --- a/libgo/go/crypto/dsa/dsa.go +++ b/libgo/go/crypto/dsa/dsa.go @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3 +// Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3. package dsa import ( diff --git a/libgo/go/crypto/md5/md5_test.go b/libgo/go/crypto/md5/md5_test.go index b15e466..aae8754 100644 --- a/libgo/go/crypto/md5/md5_test.go +++ b/libgo/go/crypto/md5/md5_test.go @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -package md5 +package md5_test import ( + "crypto/md5" "fmt" "io" "testing" @@ -52,7 +53,7 @@ var golden = []md5Test{ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] - c := New() + c := md5.New() for j := 0; j < 3; j++ { if j < 2 { io.WriteString(c, g.in) @@ -69,3 +70,11 @@ func TestGolden(t *testing.T) { } } } + +func ExampleNew() { + h := md5.New() + io.WriteString(h, "The fog is getting thicker!") + io.WriteString(h, "And Leon's getting laaarger!") + fmt.Printf("%x", h.Sum(nil)) + // Output: e2c569be17396eca2a2e3c11578123ed +} diff --git a/libgo/go/crypto/sha1/sha1_test.go b/libgo/go/crypto/sha1/sha1_test.go index c23df6c..2dc14ac 100644 --- a/libgo/go/crypto/sha1/sha1_test.go +++ b/libgo/go/crypto/sha1/sha1_test.go @@ -4,9 +4,10 @@ // SHA1 hash algorithm. See RFC 3174. -package sha1 +package sha1_test import ( + "crypto/sha1" "fmt" "io" "testing" @@ -54,7 +55,7 @@ var golden = []sha1Test{ func TestGolden(t *testing.T) { for i := 0; i < len(golden); i++ { g := golden[i] - c := New() + c := sha1.New() for j := 0; j < 3; j++ { if j < 2 { io.WriteString(c, g.in) @@ -71,3 +72,10 @@ func TestGolden(t *testing.T) { } } } + +func ExampleNew() { + h := sha1.New() + io.WriteString(h, "His money is twice tainted: 'taint yours and 'taint mine.") + fmt.Printf("% x", h.Sum(nil)) + // Output: 59 7f 6a 54 00 10 f9 4c 15 d7 18 06 a9 9a 2c 87 10 e7 47 bd +} diff --git a/libgo/go/crypto/tls/handshake_client.go b/libgo/go/crypto/tls/handshake_client.go index 687e5ef..0d7b806 100644 --- a/libgo/go/crypto/tls/handshake_client.go +++ b/libgo/go/crypto/tls/handshake_client.go @@ -273,7 +273,7 @@ func (c *Conn) clientHandshake() error { masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromPreMasterSecret(c.vers, preMasterSecret, hello.random, serverHello.random, suite.macLen, suite.keyLen, suite.ivLen) - clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */ ) + clientCipher := suite.cipher(clientKey, clientIV, false /* not for reading */) clientHash := suite.mac(c.vers, clientMAC) c.out.prepareCipherSpec(c.vers, clientCipher, clientHash) c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) @@ -294,7 +294,7 @@ func (c *Conn) clientHandshake() error { finishedHash.Write(finished.marshal()) c.writeRecord(recordTypeHandshake, finished.marshal()) - serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */ ) + serverCipher := suite.cipher(serverKey, serverIV, true /* for reading */) serverHash := suite.mac(c.vers, serverMAC) c.in.prepareCipherSpec(c.vers, serverCipher, serverHash) c.readRecord(recordTypeChangeCipherSpec) diff --git a/libgo/go/crypto/tls/handshake_server.go b/libgo/go/crypto/tls/handshake_server.go index fb53767..23ec558 100644 --- a/libgo/go/crypto/tls/handshake_server.go +++ b/libgo/go/crypto/tls/handshake_server.go @@ -295,7 +295,7 @@ FindCipherSuite: masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV := keysFromPreMasterSecret(c.vers, preMasterSecret, clientHello.random, hello.random, suite.macLen, suite.keyLen, suite.ivLen) - clientCipher := suite.cipher(clientKey, clientIV, true /* for reading */ ) + clientCipher := suite.cipher(clientKey, clientIV, true /* for reading */) clientHash := suite.mac(c.vers, clientMAC) c.in.prepareCipherSpec(c.vers, clientCipher, clientHash) c.readRecord(recordTypeChangeCipherSpec) @@ -333,7 +333,7 @@ FindCipherSuite: finishedHash.Write(clientFinished.marshal()) - serverCipher := suite.cipher(serverKey, serverIV, false /* not for reading */ ) + serverCipher := suite.cipher(serverKey, serverIV, false /* not for reading */) serverHash := suite.mac(c.vers, serverMAC) c.out.prepareCipherSpec(c.vers, serverCipher, serverHash) c.writeRecord(recordTypeChangeCipherSpec, []byte{1}) diff --git a/libgo/go/database/sql/convert.go b/libgo/go/database/sql/convert.go index 4afa2be..bfcb03c 100644 --- a/libgo/go/database/sql/convert.go +++ b/libgo/go/database/sql/convert.go @@ -17,8 +17,8 @@ import ( // subsetTypeArgs takes a slice of arguments from callers of the sql // package and converts them into a slice of the driver package's // "subset types". -func subsetTypeArgs(args []interface{}) ([]interface{}, error) { - out := make([]interface{}, len(args)) +func subsetTypeArgs(args []interface{}) ([]driver.Value, error) { + out := make([]driver.Value, len(args)) for n, arg := range args { var err error out[n], err = driver.DefaultParameterConverter.ConvertValue(arg) diff --git a/libgo/go/database/sql/driver/driver.go b/libgo/go/database/sql/driver/driver.go index b930077..7f986b8 100644 --- a/libgo/go/database/sql/driver/driver.go +++ b/libgo/go/database/sql/driver/driver.go @@ -6,21 +6,20 @@ // drivers as used by package sql. // // Most code should use package sql. -// -// Drivers only need to be aware of a subset of Go's types. The sql package -// will convert all types into one of the following: +package driver + +import "errors" + +// A driver Value is a value that drivers must be able to handle. +// A Value is either nil or an instance of one of these types: // // int64 // float64 // bool -// nil // []byte // string [*] everywhere except from Rows.Next. // time.Time -// -package driver - -import "errors" +type Value interface{} // Driver is the interface that must be implemented by a database // driver. @@ -50,11 +49,9 @@ var ErrSkip = errors.New("driver: skip fast-path; continue as if unimplemented") // first prepare a query, execute the statement, and then close the // statement. // -// All arguments are of a subset type as defined in the package docs. -// // Exec may return ErrSkip. type Execer interface { - Exec(query string, args []interface{}) (Result, error) + Exec(query string, args []Value) (Result, error) } // Conn is a connection to a database. It is not used concurrently @@ -127,18 +124,17 @@ type Stmt interface { NumInput() int // Exec executes a query that doesn't return rows, such - // as an INSERT or UPDATE. The args are all of a subset - // type as defined above. - Exec(args []interface{}) (Result, error) + // as an INSERT or UPDATE. + Exec(args []Value) (Result, error) // Exec executes a query that may return rows, such as a - // SELECT. The args of all of a subset type as defined above. - Query(args []interface{}) (Rows, error) + // SELECT. + Query(args []Value) (Rows, error) } // ColumnConverter may be optionally implemented by Stmt if the // the statement is aware of its own columns' types and can -// convert from any type to a driver subset type. +// convert from any type to a driver Value. type ColumnConverter interface { // ColumnConverter returns a ValueConverter for the provided // column index. If the type of a specific column isn't known @@ -162,12 +158,12 @@ type Rows interface { // the provided slice. The provided slice will be the same // size as the Columns() are wide. // - // The dest slice may be populated with only with values - // of subset types defined above, but excluding string. + // The dest slice may be populated only with + // a driver Value type, but excluding string. // All string values must be converted to []byte. // // Next should return io.EOF when there are no more rows. - Next(dest []interface{}) error + Next(dest []Value) error } // Tx is a transaction. @@ -190,18 +186,19 @@ func (v RowsAffected) RowsAffected() (int64, error) { return int64(v), nil } -// DDLSuccess is a pre-defined Result for drivers to return when a DDL -// command succeeds. -var DDLSuccess ddlSuccess +// ResultNoRows is a pre-defined Result for drivers to return when a DDL +// command (such as a CREATE TABLE) succeeds. It returns an error for both +// LastInsertId and RowsAffected. +var ResultNoRows noRows -type ddlSuccess struct{} +type noRows struct{} -var _ Result = ddlSuccess{} +var _ Result = noRows{} -func (ddlSuccess) LastInsertId() (int64, error) { +func (noRows) LastInsertId() (int64, error) { return 0, errors.New("no LastInsertId available after DDL statement") } -func (ddlSuccess) RowsAffected() (int64, error) { +func (noRows) RowsAffected() (int64, error) { return 0, errors.New("no RowsAffected available after DDL statement") } diff --git a/libgo/go/database/sql/driver/types.go b/libgo/go/database/sql/driver/types.go index ce3c943..3305354 100644 --- a/libgo/go/database/sql/driver/types.go +++ b/libgo/go/database/sql/driver/types.go @@ -17,28 +17,28 @@ import ( // driver package to provide consistent implementations of conversions // between drivers. The ValueConverters have several uses: // -// * converting from the subset types as provided by the sql package +// * converting from the Value types as provided by the sql package // into a database table's specific column type and making sure it // fits, such as making sure a particular int64 fits in a // table's uint16 column. // // * converting a value as given from the database into one of the -// subset types. +// driver Value types. // -// * by the sql package, for converting from a driver's subset type +// * by the sql package, for converting from a driver's Value type // to a user's type in a scan. type ValueConverter interface { - // ConvertValue converts a value to a restricted subset type. - ConvertValue(v interface{}) (interface{}, error) + // ConvertValue converts a value to a driver Value. + ConvertValue(v interface{}) (Value, error) } -// SubsetValuer is the interface providing the SubsetValue method. +// Valuer is the interface providing the Value method. // -// Types implementing SubsetValuer interface are able to convert -// themselves to one of the driver's allowed subset values. -type SubsetValuer interface { - // SubsetValue returns a driver parameter subset value. - SubsetValue() (interface{}, error) +// Types implementing Valuer interface are able to convert +// themselves to a driver Value. +type Valuer interface { + // Value returns a driver Value. + Value() (Value, error) } // Bool is a ValueConverter that converts input values to bools. @@ -59,7 +59,7 @@ var _ ValueConverter = boolType{} func (boolType) String() string { return "Bool" } -func (boolType) ConvertValue(src interface{}) (interface{}, error) { +func (boolType) ConvertValue(src interface{}) (Value, error) { switch s := src.(type) { case bool: return s, nil @@ -104,7 +104,7 @@ type int32Type struct{} var _ ValueConverter = int32Type{} -func (int32Type) ConvertValue(v interface{}) (interface{}, error) { +func (int32Type) ConvertValue(v interface{}) (Value, error) { rv := reflect.ValueOf(v) switch rv.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: @@ -137,7 +137,7 @@ var String stringType type stringType struct{} -func (stringType) ConvertValue(v interface{}) (interface{}, error) { +func (stringType) ConvertValue(v interface{}) (Value, error) { switch v.(type) { case string, []byte: return v, nil @@ -151,7 +151,7 @@ type Null struct { Converter ValueConverter } -func (n Null) ConvertValue(v interface{}) (interface{}, error) { +func (n Null) ConvertValue(v interface{}) (Value, error) { if v == nil { return nil, nil } @@ -164,28 +164,17 @@ type NotNull struct { Converter ValueConverter } -func (n NotNull) ConvertValue(v interface{}) (interface{}, error) { +func (n NotNull) ConvertValue(v interface{}) (Value, error) { if v == nil { return nil, fmt.Errorf("nil value not allowed") } return n.Converter.ConvertValue(v) } -// IsParameterSubsetType reports whether v is of a valid type for a -// parameter. These types are: -// -// int64 -// float64 -// bool -// nil -// []byte -// time.Time -// string -// -// This is the same list as IsScanSubsetType, with the addition of -// string. -func IsParameterSubsetType(v interface{}) bool { - if IsScanSubsetType(v) { +// IsValue reports whether v is a valid Value parameter type. +// Unlike IsScanValue, IsValue permits the string type. +func IsValue(v interface{}) bool { + if IsScanValue(v) { return true } if _, ok := v.(string); ok { @@ -194,18 +183,9 @@ func IsParameterSubsetType(v interface{}) bool { return false } -// IsScanSubsetType reports whether v is of a valid type for a -// value populated by Rows.Next. These types are: -// -// int64 -// float64 -// bool -// nil -// []byte -// time.Time -// -// This is the same list as IsParameterSubsetType, without string. -func IsScanSubsetType(v interface{}) bool { +// IsScanValue reports whether v is a valid Value scan type. +// Unlike IsValue, IsScanValue does not permit the string type. +func IsScanValue(v interface{}) bool { if v == nil { return true } @@ -221,7 +201,7 @@ func IsScanSubsetType(v interface{}) bool { // ColumnConverter. // // DefaultParameterConverter returns the given value directly if -// IsSubsetType(value). Otherwise integer type are converted to +// IsValue(value). Otherwise integer type are converted to // int64, floats to float64, and strings to []byte. Other types are // an error. var DefaultParameterConverter defaultConverter @@ -230,18 +210,18 @@ type defaultConverter struct{} var _ ValueConverter = defaultConverter{} -func (defaultConverter) ConvertValue(v interface{}) (interface{}, error) { - if IsParameterSubsetType(v) { +func (defaultConverter) ConvertValue(v interface{}) (Value, error) { + if IsValue(v) { return v, nil } - if svi, ok := v.(SubsetValuer); ok { - sv, err := svi.SubsetValue() + if svi, ok := v.(Valuer); ok { + sv, err := svi.Value() if err != nil { return nil, err } - if !IsParameterSubsetType(sv) { - return nil, fmt.Errorf("non-subset type %T returned from SubsetValue", sv) + if !IsValue(sv) { + return nil, fmt.Errorf("non-Value type %T returned from Value", sv) } return sv, nil } diff --git a/libgo/go/database/sql/fakedb_test.go b/libgo/go/database/sql/fakedb_test.go index 889e2a2..fc63f03 100644 --- a/libgo/go/database/sql/fakedb_test.go +++ b/libgo/go/database/sql/fakedb_test.go @@ -217,7 +217,7 @@ func (c *fakeConn) Close() error { return nil } -func checkSubsetTypes(args []interface{}) error { +func checkSubsetTypes(args []driver.Value) error { for n, arg := range args { switch arg.(type) { case int64, float64, bool, nil, []byte, string, time.Time: @@ -228,7 +228,7 @@ func checkSubsetTypes(args []interface{}) error { return nil } -func (c *fakeConn) Exec(query string, args []interface{}) (driver.Result, error) { +func (c *fakeConn) Exec(query string, args []driver.Value) (driver.Result, error) { // This is an optional interface, but it's implemented here // just to check that all the args of of the proper types. // ErrSkip is returned so the caller acts as if we didn't @@ -379,7 +379,7 @@ func (s *fakeStmt) Close() error { var errClosed = errors.New("fakedb: statement has been closed") -func (s *fakeStmt) Exec(args []interface{}) (driver.Result, error) { +func (s *fakeStmt) Exec(args []driver.Value) (driver.Result, error) { if s.closed { return nil, errClosed } @@ -392,12 +392,12 @@ func (s *fakeStmt) Exec(args []interface{}) (driver.Result, error) { switch s.cmd { case "WIPE": db.wipe() - return driver.DDLSuccess, nil + return driver.ResultNoRows, nil case "CREATE": if err := db.createTable(s.table, s.colName, s.colType); err != nil { return nil, err } - return driver.DDLSuccess, nil + return driver.ResultNoRows, nil case "INSERT": return s.execInsert(args) } @@ -405,7 +405,7 @@ func (s *fakeStmt) Exec(args []interface{}) (driver.Result, error) { return nil, fmt.Errorf("unimplemented statement Exec command type of %q", s.cmd) } -func (s *fakeStmt) execInsert(args []interface{}) (driver.Result, error) { +func (s *fakeStmt) execInsert(args []driver.Value) (driver.Result, error) { db := s.c.db if len(args) != s.placeholders { panic("error in pkg db; should only get here if size is correct") @@ -441,7 +441,7 @@ func (s *fakeStmt) execInsert(args []interface{}) (driver.Result, error) { return driver.RowsAffected(1), nil } -func (s *fakeStmt) Query(args []interface{}) (driver.Rows, error) { +func (s *fakeStmt) Query(args []driver.Value) (driver.Rows, error) { if s.closed { return nil, errClosed } @@ -548,7 +548,7 @@ func (rc *rowsCursor) Columns() []string { return rc.cols } -func (rc *rowsCursor) Next(dest []interface{}) error { +func (rc *rowsCursor) Next(dest []driver.Value) error { if rc.closed { return errors.New("fakedb: cursor is closed") } diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go index f14a98c..62b551d 100644 --- a/libgo/go/database/sql/sql.go +++ b/libgo/go/database/sql/sql.go @@ -62,8 +62,8 @@ func (ns *NullString) Scan(value interface{}) error { return convertAssign(&ns.String, value) } -// SubsetValue implements the driver SubsetValuer interface. -func (ns NullString) SubsetValue() (interface{}, error) { +// Value implements the driver Valuer interface. +func (ns NullString) Value() (driver.Value, error) { if !ns.Valid { return nil, nil } @@ -88,8 +88,8 @@ func (n *NullInt64) Scan(value interface{}) error { return convertAssign(&n.Int64, value) } -// SubsetValue implements the driver SubsetValuer interface. -func (n NullInt64) SubsetValue() (interface{}, error) { +// Value implements the driver Valuer interface. +func (n NullInt64) Value() (driver.Value, error) { if !n.Valid { return nil, nil } @@ -114,8 +114,8 @@ func (n *NullFloat64) Scan(value interface{}) error { return convertAssign(&n.Float64, value) } -// SubsetValue implements the driver SubsetValuer interface. -func (n NullFloat64) SubsetValue() (interface{}, error) { +// Value implements the driver Valuer interface. +func (n NullFloat64) Value() (driver.Value, error) { if !n.Valid { return nil, nil } @@ -140,8 +140,8 @@ func (n *NullBool) Scan(value interface{}) error { return convertAssign(&n.Bool, value) } -// SubsetValue implements the driver SubsetValuer interface. -func (n NullBool) SubsetValue() (interface{}, error) { +// Value implements the driver Valuer interface. +func (n NullBool) Value() (driver.Value, error) { if !n.Valid { return nil, nil } @@ -523,8 +523,13 @@ func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) { } defer tx.releaseConn() + sargs, err := subsetTypeArgs(args) + if err != nil { + return nil, err + } + if execer, ok := ci.(driver.Execer); ok { - resi, err := execer.Exec(query, args) + resi, err := execer.Exec(query, sargs) if err == nil { return result{resi}, nil } @@ -539,11 +544,6 @@ func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) { } defer sti.Close() - sargs, err := subsetTypeArgs(args) - if err != nil { - return nil, err - } - resi, err := sti.Exec(sargs) if err != nil { return nil, err @@ -618,19 +618,21 @@ func (s *Stmt) Exec(args ...interface{}) (Result, error) { return nil, fmt.Errorf("sql: expected %d arguments, got %d", want, len(args)) } + sargs := make([]driver.Value, len(args)) + // Convert args to subset types. if cc, ok := si.(driver.ColumnConverter); ok { for n, arg := range args { // First, see if the value itself knows how to convert // itself to a driver type. For example, a NullString // struct changing into a string or nil. - if svi, ok := arg.(driver.SubsetValuer); ok { - sv, err := svi.SubsetValue() + if svi, ok := arg.(driver.Valuer); ok { + sv, err := svi.Value() if err != nil { - return nil, fmt.Errorf("sql: argument index %d from SubsetValue: %v", n, err) + return nil, fmt.Errorf("sql: argument index %d from Value: %v", n, err) } - if !driver.IsParameterSubsetType(sv) { - return nil, fmt.Errorf("sql: argument index %d: non-subset type %T returned from SubsetValue", n, sv) + if !driver.IsValue(sv) { + return nil, fmt.Errorf("sql: argument index %d: non-subset type %T returned from Value", n, sv) } arg = sv } @@ -642,25 +644,25 @@ func (s *Stmt) Exec(args ...interface{}) (Result, error) { // truncated), or that a nil can't go into a NOT NULL // column before going across the network to get the // same error. - args[n], err = cc.ColumnConverter(n).ConvertValue(arg) + sargs[n], err = cc.ColumnConverter(n).ConvertValue(arg) if err != nil { return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err) } - if !driver.IsParameterSubsetType(args[n]) { + if !driver.IsValue(sargs[n]) { return nil, fmt.Errorf("sql: driver ColumnConverter error converted %T to unsupported type %T", - arg, args[n]) + arg, sargs[n]) } } } else { for n, arg := range args { - args[n], err = driver.DefaultParameterConverter.ConvertValue(arg) + sargs[n], err = driver.DefaultParameterConverter.ConvertValue(arg) if err != nil { return nil, fmt.Errorf("sql: converting Exec argument #%d's type: %v", n, err) } } } - resi, err := si.Exec(args) + resi, err := si.Exec(sargs) if err != nil { return nil, err } @@ -829,7 +831,7 @@ type Rows struct { rowsi driver.Rows closed bool - lastcols []interface{} + lastcols []driver.Value lasterr error closeStmt *Stmt // if non-nil, statement to Close on close } @@ -846,7 +848,7 @@ func (rs *Rows) Next() bool { return false } if rs.lastcols == nil { - rs.lastcols = make([]interface{}, len(rs.rowsi.Columns())) + rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns())) } rs.lasterr = rs.rowsi.Next(rs.lastcols) if rs.lasterr == io.EOF { diff --git a/libgo/go/debug/dwarf/open.go b/libgo/go/debug/dwarf/open.go index 9543297..37a518b 100644 --- a/libgo/go/debug/dwarf/open.go +++ b/libgo/go/debug/dwarf/open.go @@ -31,8 +31,9 @@ type Data struct { } // New returns a new Data object initialized from the given parameters. -// Clients should typically use [TODO(rsc): method to be named later] instead of calling -// New directly. +// Rather than calling this function directly, clients should typically use +// the DWARF method of the File type of the appropriate package debug/elf, +// debug/macho, or debug/pe. // // The []byte arguments are the data from the corresponding debug section // in the object file; for example, for an ELF object, abbrev is the contents of diff --git a/libgo/go/debug/dwarf/testdata/typedef.c b/libgo/go/debug/dwarf/testdata/typedef.c index 664d021..f05f015 100644 --- a/libgo/go/debug/dwarf/testdata/typedef.c +++ b/libgo/go/debug/dwarf/testdata/typedef.c @@ -28,8 +28,13 @@ typedef struct my_struct { volatile int vi; char x : 1; int y : 4; + int z[0]; long long array[40]; + int zz[0]; } t_my_struct; +typedef struct my_struct1 { + int zz [1]; +} t_my_struct1; typedef union my_union { volatile int vi; char x : 1; @@ -65,7 +70,8 @@ t_func_void_of_char *a9; t_func_void_of_void *a10; t_func_void_of_ptr_char_dots *a11; t_my_struct *a12; -t_my_union *a12a; +t_my_struct1 *a12a; +t_my_union *a12b; t_my_enum *a13; t_my_list *a14; t_my_tree *a15; diff --git a/libgo/go/debug/dwarf/testdata/typedef.elf b/libgo/go/debug/dwarf/testdata/typedef.elf index 44df8da..b2062d2 100755 Binary files a/libgo/go/debug/dwarf/testdata/typedef.elf and b/libgo/go/debug/dwarf/testdata/typedef.elf differ diff --git a/libgo/go/debug/dwarf/testdata/typedef.macho b/libgo/go/debug/dwarf/testdata/typedef.macho index 41019c1..f75afccc 100644 Binary files a/libgo/go/debug/dwarf/testdata/typedef.macho and b/libgo/go/debug/dwarf/testdata/typedef.macho differ diff --git a/libgo/go/debug/dwarf/type.go b/libgo/go/debug/dwarf/type.go index 9be6665..4502355 100644 --- a/libgo/go/debug/dwarf/type.go +++ b/libgo/go/debug/dwarf/type.go @@ -426,6 +426,8 @@ func (d *Data) Type(off Offset) (Type, error) { t.StructName, _ = e.Val(AttrName).(string) t.Incomplete = e.Val(AttrDeclaration) != nil t.Field = make([]*StructField, 0, 8) + var lastFieldType Type + var lastFieldBitOffset int64 for kid := next(); kid != nil; kid = next() { if kid.Tag == TagMember { f := new(StructField) @@ -444,11 +446,32 @@ func (d *Data) Type(off Offset) (Type, error) { goto Error } } + + haveBitOffset := false f.Name, _ = kid.Val(AttrName).(string) f.ByteSize, _ = kid.Val(AttrByteSize).(int64) - f.BitOffset, _ = kid.Val(AttrBitOffset).(int64) + f.BitOffset, haveBitOffset = kid.Val(AttrBitOffset).(int64) f.BitSize, _ = kid.Val(AttrBitSize).(int64) t.Field = append(t.Field, f) + + bito := f.BitOffset + if !haveBitOffset { + bito = f.ByteOffset * 8 + } + if bito == lastFieldBitOffset && t.Kind != "union" { + // Last field was zero width. Fix array length. + // (DWARF writes out 0-length arrays as if they were 1-length arrays.) + zeroArray(lastFieldType) + } + lastFieldType = f.Type + lastFieldBitOffset = bito + } + } + if t.Kind != "union" { + b, ok := e.Val(AttrByteSize).(int64) + if ok && b*8 == lastFieldBitOffset { + // Final field must be zero width. Fix array length. + zeroArray(lastFieldType) } } @@ -579,3 +602,14 @@ Error: delete(d.typeCache, off) return nil, err } + +func zeroArray(t Type) { + for { + at, ok := t.(*ArrayType) + if !ok { + break + } + at.Count = 0 + t = at.Type + } +} diff --git a/libgo/go/debug/dwarf/type_test.go b/libgo/go/debug/dwarf/type_test.go index b9470a4..b5b255f 100644 --- a/libgo/go/debug/dwarf/type_test.go +++ b/libgo/go/debug/dwarf/type_test.go @@ -25,13 +25,22 @@ var typedefTests = map[string]string{ "t_func_void_of_char": "func(char) void", "t_func_void_of_void": "func() void", "t_func_void_of_ptr_char_dots": "func(*char, ...) void", - "t_my_struct": "struct my_struct {vi volatile int@0; x char@4 : 1@7; y int@4 : 4@27; array [40]long long int@8}", + "t_my_struct": "struct my_struct {vi volatile int@0; x char@4 : 1@7; y int@4 : 4@27; z [0]int@8; array [40]long long int@8; zz [0]int@328}", + "t_my_struct1": "struct my_struct1 {zz [1]int@0}", "t_my_union": "union my_union {vi volatile int@0; x char@0 : 1@7; y int@0 : 4@28; array [40]long long int@0}", "t_my_enum": "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}", "t_my_list": "struct list {val short int@0; next *t_my_list@8}", "t_my_tree": "struct tree {left *struct tree@0; right *struct tree@8; val long long unsigned int@16}", } +// As Apple converts gcc to a clang-based front end +// they keep breaking the DWARF output. This map lists the +// conversion from real answer to Apple answer. +var machoBug = map[string]string{ + "func(*char, ...) void": "func(*char) void", + "enum my_enum {e1=1; e2=2; e3=-5; e4=1000000000000000}": "enum my_enum {e1=1; e2=2; e3=-5; e4=-1530494976}", +} + func elfData(t *testing.T, name string) *Data { f, err := elf.Open(name) if err != nil { @@ -58,13 +67,13 @@ func machoData(t *testing.T, name string) *Data { return d } -func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf")) } +func TestTypedefsELF(t *testing.T) { testTypedefs(t, elfData(t, "testdata/typedef.elf"), "elf") } func TestTypedefsMachO(t *testing.T) { - testTypedefs(t, machoData(t, "testdata/typedef.macho")) + testTypedefs(t, machoData(t, "testdata/typedef.macho"), "macho") } -func testTypedefs(t *testing.T, d *Data) { +func testTypedefs(t *testing.T, d *Data, kind string) { r := d.Reader() seen := make(map[string]bool) for { @@ -93,7 +102,7 @@ func testTypedefs(t *testing.T, d *Data) { t.Errorf("multiple definitions for %s", t1.Name) } seen[t1.Name] = true - if typstr != want { + if typstr != want && (kind != "macho" || typstr != machoBug[want]) { t.Errorf("%s:\n\thave %s\n\twant %s", t1.Name, typstr, want) } } diff --git a/libgo/go/debug/gosym/pclntab_test.go b/libgo/go/debug/gosym/pclntab_test.go index b90181b..b2400bb 100644 --- a/libgo/go/debug/gosym/pclntab_test.go +++ b/libgo/go/debug/gosym/pclntab_test.go @@ -6,15 +6,37 @@ package gosym import ( "debug/elf" + "fmt" "os" + "os/exec" "runtime" + "strings" "testing" ) +var pclinetestBinary string + func dotest() bool { // For now, only works on ELF platforms. - // TODO: convert to work with new go tool - return false && runtime.GOOS == "linux" && runtime.GOARCH == "amd64" + if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" { + return false + } + if pclinetestBinary != "" { + return true + } + // This command builds pclinetest from pclinetest.asm; + // the resulting binary looks like it was built from pclinetest.s, + // but we have renamed it to keep it away from the go tool. + pclinetestBinary = os.TempDir() + "/pclinetest" + command := fmt.Sprintf("go tool 6a -o %s.6 pclinetest.asm && go tool 6l -E main -o %s %s.6", + pclinetestBinary, pclinetestBinary, pclinetestBinary) + cmd := exec.Command("sh", "-c", command) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + if err := cmd.Run(); err != nil { + panic(err) + } + return true } func getTable(t *testing.T) *Table { @@ -149,7 +171,7 @@ func TestPCLine(t *testing.T) { return } - f, tab := crack("_test/pclinetest", t) + f, tab := crack(pclinetestBinary, t) text := f.Section(".text") textdat, err := text.Data() if err != nil { @@ -163,10 +185,13 @@ func TestPCLine(t *testing.T) { file, line, fn := tab.PCToLine(pc) off := pc - text.Addr // TODO(rsc): should not need off; bug in 8g wantLine += int(textdat[off]) + t.Logf("off is %d", off) if fn == nil { t.Errorf("failed to get line of PC %#x", pc) - } else if len(file) < 12 || file[len(file)-12:] != "pclinetest.s" || line != wantLine || fn != sym { - t.Errorf("expected %s:%d (%s) at PC %#x, got %s:%d (%s)", "pclinetest.s", wantLine, sym.Name, pc, file, line, fn.Name) + } else if !strings.HasSuffix(file, "pclinetest.asm") { + t.Errorf("expected %s (%s) at PC %#x, got %s (%s)", "pclinetest.asm", sym.Name, pc, file, fn.Name) + } else if line != wantLine || fn != sym { + t.Errorf("expected :%d (%s) at PC %#x, got :%d (%s)", wantLine, sym.Name, pc, line, fn.Name) } } diff --git a/libgo/go/encoding/gob/decode.go b/libgo/go/encoding/gob/decode.go index 750d623..a0bb985 100644 --- a/libgo/go/encoding/gob/decode.go +++ b/libgo/go/encoding/gob/decode.go @@ -464,7 +464,7 @@ func allocate(rtyp reflect.Type, p uintptr, indir int) uintptr { // decodeSingle decodes a top-level value that is not a struct and stores it through p. // Such values are preceded by a zero, making them have the memory layout of a // struct field (although with an illegal field number). -func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, basep uintptr) (err error) { +func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, basep uintptr) { state := dec.newDecoderState(&dec.buf) state.fieldnum = singletonField delta := int(state.decodeUint()) @@ -473,7 +473,7 @@ func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, basep uint } instr := &engine.instr[singletonField] if instr.indir != ut.indir { - return errors.New("gob: internal error: inconsistent indirection") + errorf("internal error: inconsistent indirection instr %d ut %d", instr.indir, ut.indir) } ptr := unsafe.Pointer(basep) // offset will be zero if instr.indir > 1 { @@ -481,10 +481,9 @@ func (dec *Decoder) decodeSingle(engine *decEngine, ut *userTypeInfo, basep uint } instr.op(instr, state, ptr) dec.freeDecoderState(state) - return nil } -// decodeSingle decodes a top-level struct and stores it through p. +// decodeStruct decodes a top-level struct and stores it through p. // Indir is for the value, not the type. At the time of the call it may // differ from ut.indir, which was computed when the engine was built. // This state cannot arise for decodeSingle, which is called directly @@ -839,11 +838,10 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProg } case reflect.Map: - name = "element of " + name keyId := dec.wireType[wireId].MapT.Key elemId := dec.wireType[wireId].MapT.Elem - keyOp, keyIndir := dec.decOpFor(keyId, t.Key(), name, inProgress) - elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), name, inProgress) + keyOp, keyIndir := dec.decOpFor(keyId, t.Key(), "key of "+name, inProgress) + elemOp, elemIndir := dec.decOpFor(elemId, t.Elem(), "element of "+name, inProgress) ovfl := overflow(name) op = func(i *decInstr, state *decoderState, p unsafe.Pointer) { up := unsafe.Pointer(p) @@ -1151,7 +1149,7 @@ func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEn // getDecEnginePtr returns the engine for the specified type. func (dec *Decoder) getDecEnginePtr(remoteId typeId, ut *userTypeInfo) (enginePtr **decEngine, err error) { - rt := ut.base + rt := ut.user decoderMap, ok := dec.decoderCache[rt] if !ok { decoderMap = make(map[typeId]**decEngine) diff --git a/libgo/go/encoding/gob/encoder_test.go b/libgo/go/encoding/gob/encoder_test.go index 9a62cf9..3bfae30 100644 --- a/libgo/go/encoding/gob/encoder_test.go +++ b/libgo/go/encoding/gob/encoder_test.go @@ -685,3 +685,54 @@ func TestSliceIncompatibility(t *testing.T) { t.Error("expected compatibility error") } } + +// Mutually recursive slices of structs caused problems. +type Bug3 struct { + Num int + Children []*Bug3 +} + +func TestGobPtrSlices(t *testing.T) { + in := []*Bug3{ + &Bug3{1, nil}, + &Bug3{2, nil}, + } + b := new(bytes.Buffer) + err := NewEncoder(b).Encode(&in) + if err != nil { + t.Fatal("encode:", err) + } + + var out []*Bug3 + err = NewDecoder(b).Decode(&out) + if err != nil { + t.Fatal("decode:", err) + } + if !reflect.DeepEqual(in, out) { + t.Fatal("got %v; wanted %v", out, in) + } +} + +// getDecEnginePtr cached engine for ut.base instead of ut.user so we passed +// a *map and then tried to reuse its engine to decode the inner map. +func TestPtrToMapOfMap(t *testing.T) { + Register(make(map[string]interface{})) + subdata := make(map[string]interface{}) + subdata["bar"] = "baz" + data := make(map[string]interface{}) + data["foo"] = subdata + + b := new(bytes.Buffer) + err := NewEncoder(b).Encode(data) + if err != nil { + t.Fatal("encode:", err) + } + var newData map[string]interface{} + err = NewDecoder(b).Decode(&newData) + if err != nil { + t.Fatal("decode:", err) + } + if !reflect.DeepEqual(data, newData) { + t.Fatalf("expected %v got %v", data, newData) + } +} diff --git a/libgo/go/encoding/gob/type.go b/libgo/go/encoding/gob/type.go index 39006ef..0dd7a0a 100644 --- a/libgo/go/encoding/gob/type.go +++ b/libgo/go/encoding/gob/type.go @@ -152,6 +152,10 @@ var idToType = make(map[typeId]gobType) var builtinIdToType map[typeId]gobType // set in init() after builtins are established func setTypeId(typ gobType) { + // When building recursive types, someone may get there before us. + if typ.id() != 0 { + return + } nextId++ typ.setId(nextId) idToType[nextId] = typ @@ -346,6 +350,11 @@ func newSliceType(name string) *sliceType { func (s *sliceType) init(elem gobType) { // Set our type id before evaluating the element's, in case it's our own. setTypeId(s) + // See the comments about ids in newTypeObject. Only slices and + // structs have mutual recursion. + if elem.id() == 0 { + setTypeId(elem) + } s.Elem = elem.id() } @@ -503,6 +512,13 @@ func newTypeObject(name string, ut *userTypeInfo, rt reflect.Type) (gobType, err if err != nil { return nil, err } + // Some mutually recursive types can cause us to be here while + // still defining the element. Fix the element type id here. + // We could do this more neatly by setting the id at the start of + // building every type, but that would break binary compatibility. + if gt.id() == 0 { + setTypeId(gt) + } st.Field = append(st.Field, &fieldType{f.Name, gt.id()}) } return st, nil diff --git a/libgo/go/encoding/json/decode.go b/libgo/go/encoding/json/decode.go index 87076b5..110c6fd 100644 --- a/libgo/go/encoding/json/decode.go +++ b/libgo/go/encoding/json/decode.go @@ -496,6 +496,12 @@ func (d *decodeState) object(v reflect.Value) { // Pretend this field doesn't exist. continue } + if sf.Anonymous { + // Pretend this field doesn't exist, + // so that we can do a good job with + // these in a later version. + continue + } // First, tag match tagName, _ := parseTag(tag) if tagName == key { @@ -963,3 +969,11 @@ func unquoteBytes(s []byte) (t []byte, ok bool) { } return b[0:w], true } + +// The following is issue 3069. + +// BUG(rsc): This package ignores anonymous (embedded) struct fields +// during encoding and decoding. A future version may assign meaning +// to them. To force an anonymous field to be ignored in all future +// versions of this package, use an explicit `json:"-"` tag in the struct +// definition. diff --git a/libgo/go/encoding/json/decode_test.go b/libgo/go/encoding/json/decode_test.go index 775becf..0eec586 100644 --- a/libgo/go/encoding/json/decode_test.go +++ b/libgo/go/encoding/json/decode_test.go @@ -619,3 +619,32 @@ func TestRefUnmarshal(t *testing.T) { t.Errorf("got %+v, want %+v", got, want) } } + +// Test that anonymous fields are ignored. +// We may assign meaning to them later. +func TestAnonymous(t *testing.T) { + type S struct { + T + N int + } + + data, err := Marshal(new(S)) + if err != nil { + t.Fatalf("Marshal: %v", err) + } + want := `{"N":0}` + if string(data) != want { + t.Fatalf("Marshal = %#q, want %#q", string(data), want) + } + + var s S + if err := Unmarshal([]byte(`{"T": 1, "T": {"Y": 1}, "N": 2}`), &s); err != nil { + t.Fatalf("Unmarshal: %v", err) + } + if s.N != 2 { + t.Fatal("Unmarshal: did not set N") + } + if s.T.Y != 0 { + t.Fatal("Unmarshal: did set T.Y") + } +} diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go index 83e73c0..8a794b7 100644 --- a/libgo/go/encoding/json/encode.go +++ b/libgo/go/encoding/json/encode.go @@ -538,6 +538,11 @@ func encodeFields(t reflect.Type) []encodeField { if f.PkgPath != "" { continue } + if f.Anonymous { + // We want to do a better job with these later, + // so for now pretend they don't exist. + continue + } var ef encodeField ef.i = i ef.tag = f.Name diff --git a/libgo/go/encoding/xml/marshal.go b/libgo/go/encoding/xml/marshal.go index a96c523..6c3170b 100644 --- a/libgo/go/encoding/xml/marshal.go +++ b/libgo/go/encoding/xml/marshal.go @@ -57,35 +57,14 @@ const ( // if the field value is empty. The empty values are false, 0, any // nil pointer or interface value, and any array, slice, map, or // string of length zero. +// - a non-pointer anonymous struct field is handled as if the +// fields of its value were part of the outer struct. // // If a field uses a tag "a>b>c", then the element c will be nested inside // parent elements a and b. Fields that appear next to each other that name -// the same parent will be enclosed in one XML element. For example: +// the same parent will be enclosed in one XML element. // -// type Result struct { -// XMLName xml.Name `xml:"result"` -// Id int `xml:"id,attr"` -// FirstName string `xml:"person>name>first"` -// LastName string `xml:"person>name>last"` -// Age int `xml:"person>age"` -// Height float `xml:"person>height,omitempty"` -// Married bool `xml:"person>married"` -// } -// -// xml.Marshal(&Result{Id: 13, FirstName: "John", LastName: "Doe", Age: 42}) -// -// would be marshalled as: -// -// -// -// -// John -// Doe -// -// 42 -// false -// -// +// See MarshalIndent for an example. // // Marshal will return an error if asked to marshal a channel, function, or map. func Marshal(v interface{}) ([]byte, error) { @@ -96,6 +75,22 @@ func Marshal(v interface{}) ([]byte, error) { return b.Bytes(), nil } +// MarshalIndent works like Marshal, but each XML element begins on a new +// indented line that starts with prefix and is followed by one or more +// copies of indent according to the nesting depth. +func MarshalIndent(v interface{}, prefix, indent string) ([]byte, error) { + var b bytes.Buffer + enc := NewEncoder(&b) + enc.prefix = prefix + enc.indent = indent + err := enc.marshalValue(reflect.ValueOf(v), nil) + enc.Flush() + if err != nil { + return nil, err + } + return b.Bytes(), nil +} + // An Encoder writes XML data to an output stream. type Encoder struct { printer @@ -103,7 +98,7 @@ type Encoder struct { // NewEncoder returns a new encoder that writes to w. func NewEncoder(w io.Writer) *Encoder { - return &Encoder{printer{bufio.NewWriter(w)}} + return &Encoder{printer{Writer: bufio.NewWriter(w)}} } // Encode writes the XML encoding of v to the stream. @@ -118,8 +113,14 @@ func (enc *Encoder) Encode(v interface{}) error { type printer struct { *bufio.Writer + indent string + prefix string + depth int + indentedIn bool } +// marshalValue writes one or more XML elements representing val. +// If val was obtained from a struct field, finfo must have its details. func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { if !val.IsValid() { return nil @@ -177,6 +178,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { } } + p.writeIndent(1) p.WriteByte('<') p.WriteString(name) @@ -216,6 +218,7 @@ func (p *printer) marshalValue(val reflect.Value, finfo *fieldInfo) error { return err } + p.writeIndent(-1) p.WriteByte('<') p.WriteByte('/') p.WriteString(name) @@ -294,6 +297,7 @@ func (p *printer) marshalStruct(tinfo *typeInfo, val reflect.Value) error { if vf.Len() == 0 { continue } + p.writeIndent(0) p.WriteString("