OSDN Git Service

libgo: Update to weekly.2011-11-01.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 2 Dec 2011 19:34:41 +0000 (19:34 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 2 Dec 2011 19:34:41 +0000 (19:34 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@181938 138bc75d-0d04-0410-961f-82ee72b054a4

169 files changed:
gcc/go/gofrontend/types.cc
libgo/config.h.in
libgo/configure
libgo/configure.ac
libgo/go/archive/zip/struct.go
libgo/go/big/int.go
libgo/go/big/int_test.go
libgo/go/big/nat.go
libgo/go/big/nat_test.go
libgo/go/big/rat.go
libgo/go/big/rat_test.go
libgo/go/bufio/bufio.go
libgo/go/bufio/bufio_test.go
libgo/go/bytes/buffer.go
libgo/go/bytes/buffer_test.go
libgo/go/bytes/bytes.go
libgo/go/bytes/bytes_test.go
libgo/go/crypto/bcrypt/bcrypt_test.go
libgo/go/crypto/openpgp/error/error.go
libgo/go/crypto/rsa/rsa.go
libgo/go/crypto/tls/alert.go
libgo/go/csv/reader.go
libgo/go/csv/reader_test.go
libgo/go/csv/writer.go
libgo/go/encoding/binary/binary_test.go
libgo/go/exp/ebnf/ebnf.go
libgo/go/exp/ebnf/parser.go
libgo/go/exp/gui/x11/conn.go
libgo/go/exp/norm/composition.go
libgo/go/exp/norm/composition_test.go
libgo/go/exp/norm/maketables.go
libgo/go/exp/norm/maketesttables.go
libgo/go/exp/norm/normalize_test.go
libgo/go/exp/norm/normregtest.go
libgo/go/exp/norm/trie_test.go
libgo/go/exp/norm/triedata_test.go
libgo/go/exp/norm/triegen.go
libgo/go/exp/sql/convert_test.go
libgo/go/exp/ssh/client.go
libgo/go/exp/ssh/messages.go
libgo/go/exp/ssh/server.go
libgo/go/exp/template/html/css.go
libgo/go/exp/template/html/css_test.go
libgo/go/exp/template/html/escape_test.go
libgo/go/exp/template/html/html.go
libgo/go/exp/template/html/js.go
libgo/go/exp/types/exportdata.go
libgo/go/exp/types/gcimporter.go
libgo/go/exp/types/testdata/test0.src [new file with mode: 0644]
libgo/go/exp/types/universe.go
libgo/go/exp/winfsnotify/winfsnotify_test.go
libgo/go/expvar/expvar.go
libgo/go/fmt/doc.go
libgo/go/fmt/fmt_test.go
libgo/go/fmt/format.go
libgo/go/fmt/print.go
libgo/go/fmt/scan.go
libgo/go/fmt/scan_test.go
libgo/go/go/ast/ast.go
libgo/go/go/ast/print.go
libgo/go/go/build/build_test.go
libgo/go/go/build/dir.go
libgo/go/go/build/pkgtest/pkgtest.go
libgo/go/go/doc/doc.go
libgo/go/go/parser/parser.go
libgo/go/go/parser/parser_test.go
libgo/go/go/printer/nodes.go
libgo/go/go/scanner/errors.go
libgo/go/go/scanner/scanner.go
libgo/go/go/scanner/scanner_test.go
libgo/go/gob/codec_test.go
libgo/go/gob/decode.go
libgo/go/gob/decoder.go
libgo/go/gob/encode.go
libgo/go/gob/encoder_test.go
libgo/go/gob/error.go
libgo/go/html/entity.go
libgo/go/html/escape.go
libgo/go/html/node.go
libgo/go/html/parse.go
libgo/go/html/parse_test.go
libgo/go/html/render.go
libgo/go/html/token_test.go
libgo/go/http/cgi/host.go
libgo/go/http/reverseproxy.go
libgo/go/http/reverseproxy_test.go
libgo/go/io/io.go
libgo/go/json/decode.go
libgo/go/json/decode_test.go
libgo/go/json/encode.go
libgo/go/json/encode_test.go
libgo/go/json/scanner.go
libgo/go/json/scanner_test.go
libgo/go/json/stream.go
libgo/go/mail/message.go
libgo/go/math/all_test.go
libgo/go/math/sin.go
libgo/go/mime/grammar.go
libgo/go/mime/mediatype.go
libgo/go/net/lookup_plan9.go
libgo/go/net/lookup_test.go
libgo/go/net/net_test.go
libgo/go/net/sock_windows.go
libgo/go/net/tcpsock_plan9.go
libgo/go/net/textproto/reader.go
libgo/go/net/textproto/reader_test.go
libgo/go/net/timeout_test.go
libgo/go/old/regexp/regexp.go
libgo/go/old/template/parse.go
libgo/go/os/file.go
libgo/go/os/os_test.go
libgo/go/path/filepath/match.go
libgo/go/path/match.go
libgo/go/reflect/all_test.go
libgo/go/regexp/exec.go
libgo/go/regexp/regexp.go
libgo/go/regexp/syntax/compile.go
libgo/go/regexp/syntax/parse.go
libgo/go/regexp/syntax/parse_test.go
libgo/go/regexp/syntax/perl_groups.go
libgo/go/regexp/syntax/prog.go
libgo/go/regexp/syntax/regexp.go
libgo/go/rpc/jsonrpc/all_test.go
libgo/go/rpc/server.go
libgo/go/rpc/server_test.go
libgo/go/runtime/debug.go
libgo/go/runtime/pprof/pprof.go
libgo/go/scanner/scanner.go
libgo/go/scanner/scanner_test.go
libgo/go/smtp/smtp_test.go
libgo/go/strconv/atob.go
libgo/go/strconv/atob_test.go
libgo/go/strconv/atof.go
libgo/go/strconv/atof_test.go
libgo/go/strconv/atoi.go
libgo/go/strconv/atoi_test.go
libgo/go/strconv/fp_test.go
libgo/go/strconv/quote.go
libgo/go/strconv/quote_test.go
libgo/go/strings/reader.go
libgo/go/strings/replace_test.go
libgo/go/strings/strings.go
libgo/go/strings/strings_test.go
libgo/go/template/exec.go
libgo/go/template/exec_test.go
libgo/go/template/funcs.go
libgo/go/template/parse/lex.go
libgo/go/testing/quick/quick.go
libgo/go/time/format.go
libgo/go/time/time_test.go
libgo/go/unicode/digit.go
libgo/go/unicode/digit_test.go
libgo/go/unicode/graphic.go
libgo/go/unicode/graphic_test.go
libgo/go/unicode/letter.go
libgo/go/unicode/letter_test.go
libgo/go/unicode/script_test.go
libgo/go/utf16/utf16.go
libgo/go/utf16/utf16_test.go
libgo/go/utf8/string.go
libgo/go/utf8/string_test.go
libgo/go/utf8/utf8.go
libgo/go/utf8/utf8_test.go
libgo/go/xml/marshal_test.go
libgo/go/xml/read.go
libgo/go/xml/xml.go
libgo/runtime/go-main.c
libgo/runtime/proc.c
libgo/runtime/runtime.h

index 74d9765..f63d169 100644 (file)
@@ -5876,13 +5876,13 @@ Interface_type::do_reflection(Gogo* gogo, std::string* ret) const
   ret->append("interface {");
   if (this->methods_ != NULL)
     {
+      ret->push_back(' ');
       for (Typed_identifier_list::const_iterator p = this->methods_->begin();
           p != this->methods_->end();
           ++p)
        {
          if (p != this->methods_->begin())
-           ret->append(";");
-         ret->push_back(' ');
+           ret->append("; ");
          if (!Gogo::is_hidden_name(p->name()))
            ret->append(p->name());
          else
@@ -5898,8 +5898,9 @@ Interface_type::do_reflection(Gogo* gogo, std::string* ret) const
          sub = sub.substr(4);
          ret->append(sub);
        }
+      ret->push_back(' ');
     }
-  ret->append(" }");
+  ret->append("}");
 }
 
 // Mangled name.
index 0c1283c..f30af59 100644 (file)
 /* Define to 1 if the system has the type `off64_t'. */
 #undef HAVE_OFF64_T
 
-/* Define to 1 if you have the `random' function. */
-#undef HAVE_RANDOM
-
 /* Define to 1 if you have the `sem_timedwait' function. */
 #undef HAVE_SEM_TIMEDWAIT
 
 /* Define to 1 if you have the `setenv' function. */
 #undef HAVE_SETENV
 
-/* Define to 1 if you have the `srandom' function. */
-#undef HAVE_SRANDOM
-
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
index e9f536a..2e99887 100755 (executable)
@@ -14529,7 +14529,7 @@ else
 fi
 
 
-for ac_func in srandom random strerror_r strsignal wait4 mincore setenv
+for ac_func in strerror_r strsignal wait4 mincore setenv
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
index 576d1a6..62d4c95 100644 (file)
@@ -452,7 +452,7 @@ AC_CHECK_HEADERS([linux/filter.h linux/netlink.h linux/rtnetlink.h], [], [],
 
 AM_CONDITIONAL(HAVE_SYS_MMAN_H, test "$ac_cv_header_sys_mman_h" = yes)
 
-AC_CHECK_FUNCS(srandom random strerror_r strsignal wait4 mincore setenv)
+AC_CHECK_FUNCS(strerror_r strsignal wait4 mincore setenv)
 AM_CONDITIONAL(HAVE_STRERROR_R, test "$ac_cv_func_strerror_r" = yes)
 AM_CONDITIONAL(HAVE_WAIT4, test "$ac_cv_func_wait4" = yes)
 
index a32de5a..4f9f599 100644 (file)
@@ -60,10 +60,10 @@ type directoryEnd struct {
        comment            string
 }
 
-func recoverError(err *os.Error) {
+func recoverError(errp *os.Error) {
        if e := recover(); e != nil {
-               if osErr, ok := e.(os.Error); ok {
-                       *err = osErr
+               if err, ok := e.(os.Error); ok {
+                       *errp = err
                        return
                }
                panic(e)
index b0dde1e..db13d20 100644 (file)
@@ -302,7 +302,7 @@ func (x *Int) String() string {
        return x.abs.decimalString()
 }
 
-func charset(ch int) string {
+func charset(ch rune) string {
        switch ch {
        case 'b':
                return lowercaseDigits[0:2]
@@ -339,7 +339,7 @@ func writeMultiple(s fmt.State, text string, count int) {
 // output field width, space or zero padding, and left or
 // right justification.
 //
-func (x *Int) Format(s fmt.State, ch int) {
+func (x *Int) Format(s fmt.State, ch rune) {
        cs := charset(ch)
 
        // special cases
@@ -460,7 +460,7 @@ func (z *Int) scan(r io.RuneScanner, base int) (*Int, int, os.Error) {
 // Scan is a support routine for fmt.Scanner; it sets z to the value of
 // the scanned number. It accepts the formats 'b' (binary), 'o' (octal),
 // 'd' (decimal), 'x' (lowercase hexadecimal), and 'X' (uppercase hexadecimal).
-func (z *Int) Scan(s fmt.ScanState, ch int) os.Error {
+func (z *Int) Scan(s fmt.ScanState, ch rune) os.Error {
        s.SkipSpace() // skip leading space characters
        base := 0
        switch ch {
index fde19c2..d66bb5f 100644 (file)
@@ -536,7 +536,7 @@ func TestScan(t *testing.T) {
                buf.Reset()
                buf.WriteString(test.input)
                if _, err := fmt.Fscanf(&buf, test.format, x); err != nil {
-                       t.Errorf("#%d error: %s", i, err.String())
+                       t.Errorf("#%d error: %s", i, err)
                }
                if x.String() != test.output {
                        t.Errorf("#%d got %s; want %s", i, x.String(), test.output)
index c0769d8..fa0d7e7 100644 (file)
@@ -589,15 +589,15 @@ func (x nat) bitLen() int {
 // MaxBase is the largest number base accepted for string conversions.
 const MaxBase = 'z' - 'a' + 10 + 1 // = hexValue('z') + 1
 
-func hexValue(ch int) Word {
+func hexValue(ch rune) Word {
        d := MaxBase + 1 // illegal base
        switch {
        case '0' <= ch && ch <= '9':
-               d = ch - '0'
+               d = int(ch - '0')
        case 'a' <= ch && ch <= 'z':
-               d = ch - 'a' + 10
+               d = int(ch - 'a' + 10)
        case 'A' <= ch && ch <= 'Z':
-               d = ch - 'A' + 10
+               d = int(ch - 'A' + 10)
        }
        return Word(d)
 }
index 4f57328..ab34c6e 100644 (file)
@@ -231,7 +231,7 @@ var natScanTests = []struct {
        x    nat    // expected nat
        b    int    // expected base
        ok   bool   // expected success
-       next int    // next character (or 0, if at EOF)
+       next rune   // next character (or 0, if at EOF)
 }{
        // error: illegal base
        {base: -1},
index 6b86062..1940a05 100644 (file)
@@ -249,13 +249,13 @@ func (z *Rat) Quo(x, y *Rat) *Rat {
        return z.norm()
 }
 
-func ratTok(ch int) bool {
+func ratTok(ch rune) bool {
        return strings.IndexRune("+-/0123456789.eE", ch) >= 0
 }
 
 // Scan is a support routine for fmt.Scanner. It accepts the formats
 // 'e', 'E', 'f', 'F', 'g', 'G', and 'v'. All formats are equivalent.
-func (z *Rat) Scan(s fmt.ScanState, ch int) os.Error {
+func (z *Rat) Scan(s fmt.ScanState, ch rune) os.Error {
        tok, err := s.Token(true, ratTok)
        if err != nil {
                return err
index a95e5fe..2443450 100644 (file)
@@ -112,7 +112,7 @@ func TestRatScan(t *testing.T) {
                _, err := fmt.Fscanf(&buf, "%v", x)
                if err == nil != test.ok {
                        if test.ok {
-                               t.Errorf("#%d error: %s", i, err.String())
+                               t.Errorf("#%d error: %s", i, err)
                        } else {
                                t.Errorf("#%d expected error", i)
                        }
index 2ea7af3..3a4e0ed 100644 (file)
@@ -208,7 +208,7 @@ func (b *Reader) UnreadByte() os.Error {
 
 // ReadRune reads a single UTF-8 encoded Unicode character and returns the
 // rune and its size in bytes.
-func (b *Reader) ReadRune() (rune int, size int, err os.Error) {
+func (b *Reader) ReadRune() (r rune, size int, err os.Error) {
        for b.r+utf8.UTFMax > b.w && !utf8.FullRune(b.buf[b.r:b.w]) && b.err == nil {
                b.fill()
        }
@@ -216,14 +216,14 @@ func (b *Reader) ReadRune() (rune int, size int, err os.Error) {
        if b.r == b.w {
                return 0, 0, b.readErr()
        }
-       rune, size = int(b.buf[b.r]), 1
-       if rune >= 0x80 {
-               rune, size = utf8.DecodeRune(b.buf[b.r:b.w])
+       r, size = rune(b.buf[b.r]), 1
+       if r >= 0x80 {
+               r, size = utf8.DecodeRune(b.buf[b.r:b.w])
        }
        b.r += size
        b.lastByte = int(b.buf[b.r-1])
        b.lastRuneSize = size
-       return rune, size, nil
+       return r, size, nil
 }
 
 // UnreadRune unreads the last rune.  If the most recent read operation on
@@ -497,9 +497,9 @@ func (b *Writer) WriteByte(c byte) os.Error {
 
 // WriteRune writes a single Unicode code point, returning
 // the number of bytes written and any error.
-func (b *Writer) WriteRune(rune int) (size int, err os.Error) {
-       if rune < utf8.RuneSelf {
-               err = b.WriteByte(byte(rune))
+func (b *Writer) WriteRune(r rune) (size int, err os.Error) {
+       if r < utf8.RuneSelf {
+               err = b.WriteByte(byte(r))
                if err != nil {
                        return 0, err
                }
@@ -516,10 +516,10 @@ func (b *Writer) WriteRune(rune int) (size int, err os.Error) {
                n = b.Available()
                if n < utf8.UTFMax {
                        // Can only happen if buffer is silly small.
-                       return b.WriteString(string(rune))
+                       return b.WriteString(string(r))
                }
        }
-       size = utf8.EncodeRune(b.buf[b.n:], rune)
+       size = utf8.EncodeRune(b.buf[b.n:], r)
        b.n += size
        return size, nil
 }
index 38213ff..4fd5f90 100644 (file)
@@ -195,14 +195,14 @@ func readRuneSegments(t *testing.T, segments []string) {
        want := strings.Join(segments, "")
        r := NewReader(&StringReader{data: segments})
        for {
-               rune, _, err := r.ReadRune()
+               r, _, err := r.ReadRune()
                if err != nil {
                        if err != os.EOF {
                                return
                        }
                        break
                }
-               got += string(rune)
+               got += string(r)
        }
        if got != want {
                t.Errorf("segments=%v got=%s want=%s", segments, got, want)
@@ -233,24 +233,24 @@ func TestUnreadRune(t *testing.T) {
        r := NewReader(&StringReader{data: segments})
        // Normal execution.
        for {
-               rune, _, err := r.ReadRune()
+               r1, _, err := r.ReadRune()
                if err != nil {
                        if err != os.EOF {
                                t.Error("unexpected EOF")
                        }
                        break
                }
-               got += string(rune)
+               got += string(r1)
                // Put it back and read it again
                if err = r.UnreadRune(); err != nil {
                        t.Error("unexpected error on UnreadRune:", err)
                }
-               rune1, _, err := r.ReadRune()
+               r2, _, err := r.ReadRune()
                if err != nil {
                        t.Error("unexpected error reading after unreading:", err)
                }
-               if rune != rune1 {
-                       t.Errorf("incorrect rune after unread: got %c wanted %c", rune1, rune)
+               if r1 != r2 {
+                       t.Errorf("incorrect rune after unread: got %c wanted %c", r1, r2)
                }
        }
        if got != data {
@@ -339,25 +339,25 @@ func TestReadWriteRune(t *testing.T) {
        w := NewWriter(byteBuf)
        // Write the runes out using WriteRune
        buf := make([]byte, utf8.UTFMax)
-       for rune := 0; rune < NRune; rune++ {
-               size := utf8.EncodeRune(buf, rune)
-               nbytes, err := w.WriteRune(rune)
+       for r := rune(0); r < NRune; r++ {
+               size := utf8.EncodeRune(buf, r)
+               nbytes, err := w.WriteRune(r)
                if err != nil {
-                       t.Fatalf("WriteRune(0x%x) error: %s", rune, err)
+                       t.Fatalf("WriteRune(0x%x) error: %s", r, err)
                }
                if nbytes != size {
-                       t.Fatalf("WriteRune(0x%x) expected %d, got %d", rune, size, nbytes)
+                       t.Fatalf("WriteRune(0x%x) expected %d, got %d", r, size, nbytes)
                }
        }
        w.Flush()
 
        r := NewReader(byteBuf)
        // Read them back with ReadRune
-       for rune := 0; rune < NRune; rune++ {
-               size := utf8.EncodeRune(buf, rune)
+       for r1 := rune(0); r1 < NRune; r1++ {
+               size := utf8.EncodeRune(buf, r1)
                nr, nbytes, err := r.ReadRune()
-               if nr != rune || nbytes != size || err != nil {
-                       t.Fatalf("ReadRune(0x%x) got 0x%x,%d not 0x%x,%d (err=%s)", r, nr, nbytes, r, size, err)
+               if nr != r1 || nbytes != size || err != nil {
+                       t.Fatalf("ReadRune(0x%x) got 0x%x,%d not 0x%x,%d (err=%s)", r1, nr, nbytes, r1, size, err)
                }
        }
 }
index 975031b..c2a8c9f 100644 (file)
@@ -188,7 +188,7 @@ func (b *Buffer) WriteByte(c byte) os.Error {
 // code point r to the buffer, returning its length and
 // an error, which is always nil but is included
 // to match bufio.Writer's WriteRune.
-func (b *Buffer) WriteRune(r int) (n int, err os.Error) {
+func (b *Buffer) WriteRune(r rune) (n int, err os.Error) {
        if r < utf8.RuneSelf {
                b.WriteByte(byte(r))
                return 1, nil
@@ -255,7 +255,7 @@ func (b *Buffer) ReadByte() (c byte, err os.Error) {
 // If no bytes are available, the error returned is os.EOF.
 // If the bytes are an erroneous UTF-8 encoding, it
 // consumes one byte and returns U+FFFD, 1.
-func (b *Buffer) ReadRune() (r int, size int, err os.Error) {
+func (b *Buffer) ReadRune() (r rune, size int, err os.Error) {
        b.lastRead = opInvalid
        if b.off >= len(b.buf) {
                // Buffer is empty, reset to recover space.
@@ -266,7 +266,7 @@ func (b *Buffer) ReadRune() (r int, size int, err os.Error) {
        c := b.buf[b.off]
        if c < utf8.RuneSelf {
                b.off++
-               return int(c), 1, nil
+               return rune(c), 1, nil
        }
        r, n := utf8.DecodeRune(b.buf[b.off:])
        b.off += n
index 06d2a65..ee38e08 100644 (file)
@@ -264,7 +264,7 @@ func TestRuneIO(t *testing.T) {
        b := make([]byte, utf8.UTFMax*NRune)
        var buf Buffer
        n := 0
-       for r := 0; r < NRune; r++ {
+       for r := rune(0); r < NRune; r++ {
                size := utf8.EncodeRune(b[n:], r)
                nbytes, err := buf.WriteRune(r)
                if err != nil {
@@ -284,7 +284,7 @@ func TestRuneIO(t *testing.T) {
 
        p := make([]byte, utf8.UTFMax)
        // Read it back with ReadRune
-       for r := 0; r < NRune; r++ {
+       for r := rune(0); r < NRune; r++ {
                size := utf8.EncodeRune(p, r)
                nr, nbytes, err := buf.ReadRune()
                if nr != r || nbytes != size || err != nil {
@@ -295,7 +295,7 @@ func TestRuneIO(t *testing.T) {
        // Check that UnreadRune works
        buf.Reset()
        buf.Write(b)
-       for r := 0; r < NRune; r++ {
+       for r := rune(0); r < NRune; r++ {
                r1, size, _ := buf.ReadRune()
                if err := buf.UnreadRune(); err != nil {
                        t.Fatalf("UnreadRune(%U) got error %q", r, err)
index 2fb4569..ac8320f 100644 (file)
@@ -130,10 +130,10 @@ func LastIndex(s, sep []byte) int {
 // IndexRune interprets s as a sequence of UTF-8-encoded Unicode code points.
 // It returns the byte index of the first occurrence in s of the given rune.
 // It returns -1 if rune is not present in s.
-func IndexRune(s []byte, rune int) int {
+func IndexRune(s []byte, r rune) int {
        for i := 0; i < len(s); {
-               r, size := utf8.DecodeRune(s[i:])
-               if r == rune {
+               r1, size := utf8.DecodeRune(s[i:])
+               if r == r1 {
                        return i
                }
                i += size
@@ -147,16 +147,17 @@ func IndexRune(s []byte, rune int) int {
 // point in common.
 func IndexAny(s []byte, chars string) int {
        if len(chars) > 0 {
-               var rune, width int
+               var r rune
+               var width int
                for i := 0; i < len(s); i += width {
-                       rune = int(s[i])
-                       if rune < utf8.RuneSelf {
+                       r = rune(s[i])
+                       if r < utf8.RuneSelf {
                                width = 1
                        } else {
-                               rune, width = utf8.DecodeRune(s[i:])
+                               r, width = utf8.DecodeRune(s[i:])
                        }
-                       for _, r := range chars {
-                               if rune == r {
+                       for _, ch := range chars {
+                               if r == ch {
                                        return i
                                }
                        }
@@ -172,10 +173,10 @@ func IndexAny(s []byte, chars string) int {
 func LastIndexAny(s []byte, chars string) int {
        if len(chars) > 0 {
                for i := len(s); i > 0; {
-                       rune, size := utf8.DecodeLastRune(s[0:i])
+                       r, size := utf8.DecodeLastRune(s[0:i])
                        i -= size
-                       for _, m := range chars {
-                               if rune == m {
+                       for _, ch := range chars {
+                               if r == ch {
                                        return i
                                }
                        }
@@ -256,13 +257,13 @@ func Fields(s []byte) [][]byte {
 // It splits the array s at each run of code points c satisfying f(c) and
 // returns a slice of subarrays of s.  If no code points in s satisfy f(c), an
 // empty slice is returned.
-func FieldsFunc(s []byte, f func(int) bool) [][]byte {
+func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
        n := 0
        inField := false
        for i := 0; i < len(s); {
-               rune, size := utf8.DecodeRune(s[i:])
+               r, size := utf8.DecodeRune(s[i:])
                wasInField := inField
-               inField = !f(rune)
+               inField = !f(r)
                if inField && !wasInField {
                        n++
                }
@@ -273,13 +274,13 @@ func FieldsFunc(s []byte, f func(int) bool) [][]byte {
        na := 0
        fieldStart := -1
        for i := 0; i <= len(s) && na < n; {
-               rune, size := utf8.DecodeRune(s[i:])
-               if fieldStart < 0 && size > 0 && !f(rune) {
+               r, size := utf8.DecodeRune(s[i:])
+               if fieldStart < 0 && size > 0 && !f(r) {
                        fieldStart = i
                        i += size
                        continue
                }
-               if fieldStart >= 0 && (size == 0 || f(rune)) {
+               if fieldStart >= 0 && (size == 0 || f(r)) {
                        a[na] = s[fieldStart:i]
                        na++
                        fieldStart = -1
@@ -329,7 +330,7 @@ func HasSuffix(s, suffix []byte) bool {
 // according to the mapping function. If mapping returns a negative value, the character is
 // dropped from the string with no replacement.  The characters in s and the
 // output are interpreted as UTF-8-encoded Unicode code points.
-func Map(mapping func(rune int) int, s []byte) []byte {
+func Map(mapping func(r rune) rune, s []byte) []byte {
        // In the worst case, the array can grow when mapped, making
        // things unpleasant.  But it's so rare we barge in assuming it's
        // fine.  It could also shrink but that falls out naturally.
@@ -338,20 +339,20 @@ func Map(mapping func(rune int) int, s []byte) []byte {
        b := make([]byte, maxbytes)
        for i := 0; i < len(s); {
                wid := 1
-               rune := int(s[i])
-               if rune >= utf8.RuneSelf {
-                       rune, wid = utf8.DecodeRune(s[i:])
+               r := rune(s[i])
+               if r >= utf8.RuneSelf {
+                       r, wid = utf8.DecodeRune(s[i:])
                }
-               rune = mapping(rune)
-               if rune >= 0 {
-                       if nbytes+utf8.RuneLen(rune) > maxbytes {
+               r = mapping(r)
+               if r >= 0 {
+                       if nbytes+utf8.RuneLen(r) > maxbytes {
                                // Grow the buffer.
                                maxbytes = maxbytes*2 + utf8.UTFMax
                                nb := make([]byte, maxbytes)
                                copy(nb, b[0:nbytes])
                                b = nb
                        }
-                       nbytes += utf8.EncodeRune(b[nbytes:maxbytes], rune)
+                       nbytes += utf8.EncodeRune(b[nbytes:maxbytes], r)
                }
                i += wid
        }
@@ -383,44 +384,44 @@ func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) }
 // ToUpperSpecial returns a copy of the byte array s with all Unicode letters mapped to their
 // upper case, giving priority to the special casing rules.
 func ToUpperSpecial(_case unicode.SpecialCase, s []byte) []byte {
-       return Map(func(r int) int { return _case.ToUpper(r) }, s)
+       return Map(func(r rune) rune { return _case.ToUpper(r) }, s)
 }
 
 // ToLowerSpecial returns a copy of the byte array s with all Unicode letters mapped to their
 // lower case, giving priority to the special casing rules.
 func ToLowerSpecial(_case unicode.SpecialCase, s []byte) []byte {
-       return Map(func(r int) int { return _case.ToLower(r) }, s)
+       return Map(func(r rune) rune { return _case.ToLower(r) }, s)
 }
 
 // ToTitleSpecial returns a copy of the byte array s with all Unicode letters mapped to their
 // title case, giving priority to the special casing rules.
 func ToTitleSpecial(_case unicode.SpecialCase, s []byte) []byte {
-       return Map(func(r int) int { return _case.ToTitle(r) }, s)
+       return Map(func(r rune) rune { return _case.ToTitle(r) }, s)
 }
 
 // isSeparator reports whether the rune could mark a word boundary.
 // TODO: update when package unicode captures more of the properties.
-func isSeparator(rune int) bool {
+func isSeparator(r rune) bool {
        // ASCII alphanumerics and underscore are not separators
-       if rune <= 0x7F {
+       if r <= 0x7F {
                switch {
-               case '0' <= rune && rune <= '9':
+               case '0' <= r && r <= '9':
                        return false
-               case 'a' <= rune && rune <= 'z':
+               case 'a' <= r && r <= 'z':
                        return false
-               case 'A' <= rune && rune <= 'Z':
+               case 'A' <= r && r <= 'Z':
                        return false
-               case rune == '_':
+               case r == '_':
                        return false
                }
                return true
        }
        // Letters and digits are not separators
-       if unicode.IsLetter(rune) || unicode.IsDigit(rune) {
+       if unicode.IsLetter(r) || unicode.IsDigit(r) {
                return false
        }
        // Otherwise, all we can do for now is treat spaces as separators.
-       return unicode.IsSpace(rune)
+       return unicode.IsSpace(r)
 }
 
 // BUG(r): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
@@ -431,9 +432,9 @@ func Title(s []byte) []byte {
        // Use a closure here to remember state.
        // Hackish but effective. Depends on Map scanning in order and calling
        // the closure once per rune.
-       prev := ' '
+       prev := rune(' ')
        return Map(
-               func(r int) int {
+               func(r rune) rune {
                        if isSeparator(prev) {
                                prev = r
                                return unicode.ToTitle(r)
@@ -446,7 +447,7 @@ func Title(s []byte) []byte {
 
 // TrimLeftFunc returns a subslice of s by slicing off all leading UTF-8-encoded
 // Unicode code points c that satisfy f(c).
-func TrimLeftFunc(s []byte, f func(r int) bool) []byte {
+func TrimLeftFunc(s []byte, f func(r rune) bool) []byte {
        i := indexFunc(s, f, false)
        if i == -1 {
                return nil
@@ -456,7 +457,7 @@ func TrimLeftFunc(s []byte, f func(r int) bool) []byte {
 
 // TrimRightFunc returns a subslice of s by slicing off all trailing UTF-8
 // encoded Unicode code points c that satisfy f(c).
-func TrimRightFunc(s []byte, f func(r int) bool) []byte {
+func TrimRightFunc(s []byte, f func(r rune) bool) []byte {
        i := lastIndexFunc(s, f, false)
        if i >= 0 && s[i] >= utf8.RuneSelf {
                _, wid := utf8.DecodeRune(s[i:])
@@ -469,36 +470,36 @@ func TrimRightFunc(s []byte, f func(r int) bool) []byte {
 
 // TrimFunc returns a subslice of s by slicing off all leading and trailing
 // UTF-8-encoded Unicode code points c that satisfy f(c).
-func TrimFunc(s []byte, f func(r int) bool) []byte {
+func TrimFunc(s []byte, f func(r rune) bool) []byte {
        return TrimRightFunc(TrimLeftFunc(s, f), f)
 }
 
 // IndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
 // It returns the byte index in s of the first Unicode
 // code point satisfying f(c), or -1 if none do.
-func IndexFunc(s []byte, f func(r int) bool) int {
+func IndexFunc(s []byte, f func(r rune) bool) int {
        return indexFunc(s, f, true)
 }
 
 // LastIndexFunc interprets s as a sequence of UTF-8-encoded Unicode code points.
 // It returns the byte index in s of the last Unicode
 // code point satisfying f(c), or -1 if none do.
-func LastIndexFunc(s []byte, f func(r int) bool) int {
+func LastIndexFunc(s []byte, f func(r rune) bool) int {
        return lastIndexFunc(s, f, true)
 }
 
 // indexFunc is the same as IndexFunc except that if
 // truth==false, the sense of the predicate function is
 // inverted.
-func indexFunc(s []byte, f func(r int) bool, truth bool) int {
+func indexFunc(s []byte, f func(r rune) bool, truth bool) int {
        start := 0
        for start < len(s) {
                wid := 1
-               rune := int(s[start])
-               if rune >= utf8.RuneSelf {
-                       rune, wid = utf8.DecodeRune(s[start:])
+               r := rune(s[start])
+               if r >= utf8.RuneSelf {
+                       r, wid = utf8.DecodeRune(s[start:])
                }
-               if f(rune) == truth {
+               if f(r) == truth {
                        return start
                }
                start += wid
@@ -509,21 +510,21 @@ func indexFunc(s []byte, f func(r int) bool, truth bool) int {
 // lastIndexFunc is the same as LastIndexFunc except that if
 // truth==false, the sense of the predicate function is
 // inverted.
-func lastIndexFunc(s []byte, f func(r int) bool, truth bool) int {
+func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int {
        for i := len(s); i > 0; {
-               rune, size := utf8.DecodeLastRune(s[0:i])
+               r, size := utf8.DecodeLastRune(s[0:i])
                i -= size
-               if f(rune) == truth {
+               if f(r) == truth {
                        return i
                }
        }
        return -1
 }
 
-func makeCutsetFunc(cutset string) func(rune int) bool {
-       return func(rune int) bool {
+func makeCutsetFunc(cutset string) func(r rune) bool {
+       return func(r rune) bool {
                for _, c := range cutset {
-                       if c == rune {
+                       if c == r {
                                return true
                        }
                }
@@ -556,8 +557,8 @@ func TrimSpace(s []byte) []byte {
 }
 
 // Runes returns a slice of runes (Unicode code points) equivalent to s.
-func Runes(s []byte) []int {
-       t := make([]int, utf8.RuneCount(s))
+func Runes(s []byte) []rune {
+       t := make([]rune, utf8.RuneCount(s))
        i := 0
        for len(s) > 0 {
                r, l := utf8.DecodeRune(s)
@@ -614,15 +615,15 @@ func Replace(s, old, new []byte, n int) []byte {
 func EqualFold(s, t []byte) bool {
        for len(s) != 0 && len(t) != 0 {
                // Extract first rune from each.
-               var sr, tr int
+               var sr, tr rune
                if s[0] < utf8.RuneSelf {
-                       sr, s = int(s[0]), s[1:]
+                       sr, s = rune(s[0]), s[1:]
                } else {
                        r, size := utf8.DecodeRune(s)
                        sr, s = r, s[size:]
                }
                if t[0] < utf8.RuneSelf {
-                       tr, t = int(t[0]), t[1:]
+                       tr, t = rune(t[0]), t[1:]
                } else {
                        r, size := utf8.DecodeRune(t)
                        tr, t = r, t[size:]
index ce3f37e..62f258d 100644 (file)
@@ -444,7 +444,7 @@ func TestFields(t *testing.T) {
 }
 
 func TestFieldsFunc(t *testing.T) {
-       pred := func(c int) bool { return c == 'X' }
+       pred := func(c rune) bool { return c == 'X' }
        var fieldsFuncTests = []FieldsTest{
                {"", []string{}},
                {"XX", []string{}},
@@ -514,24 +514,24 @@ func runStringTests(t *testing.T, f func([]byte) []byte, funcName string, testCa
        }
 }
 
-func tenRunes(rune int) string {
-       r := make([]int, 10)
-       for i := range r {
-               r[i] = rune
+func tenRunes(r rune) string {
+       runes := make([]rune, 10)
+       for i := range runes {
+               runes[i] = r
        }
-       return string(r)
+       return string(runes)
 }
 
 // User-defined self-inverse mapping function
-func rot13(rune int) int {
-       step := 13
-       if rune >= 'a' && rune <= 'z' {
-               return ((rune - 'a' + step) % 26) + 'a'
+func rot13(r rune) rune {
+       const step = 13
+       if r >= 'a' && r <= 'z' {
+               return ((r - 'a' + step) % 26) + 'a'
        }
-       if rune >= 'A' && rune <= 'Z' {
-               return ((rune - 'A' + step) % 26) + 'A'
+       if r >= 'A' && r <= 'Z' {
+               return ((r - 'A' + step) % 26) + 'A'
        }
-       return rune
+       return r
 }
 
 func TestMap(t *testing.T) {
@@ -539,7 +539,7 @@ func TestMap(t *testing.T) {
        a := tenRunes('a')
 
        // 1.  Grow.  This triggers two reallocations in Map.
-       maxRune := func(rune int) int { return unicode.MaxRune }
+       maxRune := func(r rune) rune { return unicode.MaxRune }
        m := Map(maxRune, []byte(a))
        expect := tenRunes(unicode.MaxRune)
        if string(m) != expect {
@@ -547,7 +547,7 @@ func TestMap(t *testing.T) {
        }
 
        // 2. Shrink
-       minRune := func(rune int) int { return 'a' }
+       minRune := func(r rune) rune { return 'a' }
        m = Map(minRune, []byte(tenRunes(unicode.MaxRune)))
        expect = a
        if string(m) != expect {
@@ -569,9 +569,9 @@ func TestMap(t *testing.T) {
        }
 
        // 5. Drop
-       dropNotLatin := func(rune int) int {
-               if unicode.Is(unicode.Latin, rune) {
-                       return rune
+       dropNotLatin := func(r rune) rune {
+               if unicode.Is(unicode.Latin, r) {
+                       return r
                }
                return -1
        }
@@ -615,7 +615,7 @@ func TestRepeat(t *testing.T) {
        }
 }
 
-func runesEqual(a, b []int) bool {
+func runesEqual(a, b []rune) bool {
        if len(a) != len(b) {
                return false
        }
@@ -629,18 +629,18 @@ func runesEqual(a, b []int) bool {
 
 type RunesTest struct {
        in    string
-       out   []int
+       out   []rune
        lossy bool
 }
 
 var RunesTests = []RunesTest{
-       {"", []int{}, false},
-       {" ", []int{32}, false},
-       {"ABC", []int{65, 66, 67}, false},
-       {"abc", []int{97, 98, 99}, false},
-       {"\u65e5\u672c\u8a9e", []int{26085, 26412, 35486}, false},
-       {"ab\x80c", []int{97, 98, 0xFFFD, 99}, true},
-       {"ab\xc0c", []int{97, 98, 0xFFFD, 99}, true},
+       {"", []rune{}, false},
+       {" ", []rune{32}, false},
+       {"ABC", []rune{65, 66, 67}, false},
+       {"abc", []rune{97, 98, 99}, false},
+       {"\u65e5\u672c\u8a9e", []rune{26085, 26412, 35486}, false},
+       {"ab\x80c", []rune{97, 98, 0xFFFD, 99}, true},
+       {"ab\xc0c", []rune{97, 98, 0xFFFD, 99}, true},
 }
 
 func TestRunes(t *testing.T) {
@@ -711,7 +711,7 @@ func TestTrim(t *testing.T) {
 }
 
 type predicate struct {
-       f    func(r int) bool
+       f    func(r rune) bool
        name string
 }
 
@@ -719,7 +719,7 @@ var isSpace = predicate{unicode.IsSpace, "IsSpace"}
 var isDigit = predicate{unicode.IsDigit, "IsDigit"}
 var isUpper = predicate{unicode.IsUpper, "IsUpper"}
 var isValidRune = predicate{
-       func(r int) bool {
+       func(r rune) bool {
                return r != utf8.RuneError
        },
        "IsValidRune",
@@ -732,7 +732,7 @@ type TrimFuncTest struct {
 
 func not(p predicate) predicate {
        return predicate{
-               func(r int) bool {
+               func(r rune) bool {
                        return !p.f(r)
                },
                "not " + p.name,
index 89eca0a..3efbc1c 100644 (file)
@@ -86,7 +86,7 @@ func TestInvalidHashErrors(t *testing.T) {
                        t.Errorf("%s: Should have returned an error", name)
                }
                if err != nil && err != expected {
-                       t.Errorf("%s gave err %v but should have given %v", name, err.String(), expected.String())
+                       t.Errorf("%s gave err %v but should have given %v", name, err, expected)
                }
        }
        for _, iht := range invalidTests {
index 3759ce1..9cc21f1 100644 (file)
@@ -41,21 +41,21 @@ func (b SignatureError) String() string {
        return "OpenPGP signature invalid: " + string(b)
 }
 
-type keyIncorrect int
+type keyIncorrectError int
 
-func (ki keyIncorrect) String() string {
+func (ki keyIncorrectError) String() string {
        return "the given key was incorrect"
 }
 
-var KeyIncorrectError = keyIncorrect(0)
+var KeyIncorrectError = keyIncorrectError(0)
 
-type unknownIssuer int
+type unknownIssuerError int
 
-func (unknownIssuer) String() string {
+func (unknownIssuerError) String() string {
        return "signature make by unknown entity"
 }
 
-var UnknownIssuerError = unknownIssuer(0)
+var UnknownIssuerError = unknownIssuerError(0)
 
 type UnknownPacketTypeError uint8
 
index 6957659..3df88e0 100644 (file)
@@ -116,15 +116,7 @@ func GenerateKey(random io.Reader, bits int) (priv *PrivateKey, err os.Error) {
 // [2] http://www.cacr.math.uwaterloo.ca/techreports/2006/cacr2006-16.pdf
 func GenerateMultiPrimeKey(random io.Reader, nprimes int, bits int) (priv *PrivateKey, err os.Error) {
        priv = new(PrivateKey)
-       // Smaller public exponents lead to faster public key
-       // operations. Since the exponent must be coprime to
-       // (p-1)(q-1), the smallest possible value is 3. Some have
-       // suggested that a larger exponent (often 2**16+1) be used
-       // since previous implementation bugs[1] were avoided when this
-       // was the case. However, there are no current reasons not to use
-       // small exponents.
-       // [1] http://marc.info/?l=cryptography&m=115694833312008&w=2
-       priv.E = 3
+       priv.E = 65537
 
        if nprimes < 2 {
                return nil, os.NewError("rsa.GenerateMultiPrimeKey: nprimes must be >= 2")
index 3b9e0e2..0856311 100644 (file)
@@ -71,3 +71,7 @@ func (e alert) String() string {
        }
        return "alert(" + strconv.Itoa(int(e)) + ")"
 }
+
+func (e alert) Error() string {
+       return e.String()
+}
index 29ceeae..a06b978 100644 (file)
@@ -101,8 +101,8 @@ var (
 //
 // If TrimLeadingSpace is true, leading white space in a field is ignored.
 type Reader struct {
-       Comma            int  // Field delimiter (set to ',' by NewReader)
-       Comment          int  // Comment character for start of line
+       Comma            rune // Field delimiter (set to ',' by NewReader)
+       Comment          rune // Comment character for start of line
        FieldsPerRecord  int  // Number of expected fields per record
        LazyQuotes       bool // Allow lazy quotes
        TrailingComma    bool // Allow trailing comma
@@ -173,23 +173,23 @@ func (r *Reader) ReadAll() (records [][]string, err os.Error) {
 // readRune reads one rune from r, folding \r\n to \n and keeping track
 // of how far into the line we have read.  r.column will point to the start
 // of this rune, not the end of this rune.
-func (r *Reader) readRune() (int, os.Error) {
-       rune, _, err := r.r.ReadRune()
+func (r *Reader) readRune() (rune, os.Error) {
+       r1, _, err := r.r.ReadRune()
 
        // Handle \r\n here.  We make the simplifying assumption that
        // anytime \r is followed by \n that it can be folded to \n.
        // We will not detect files which contain both \r\n and bare \n.
-       if rune == '\r' {
-               rune, _, err = r.r.ReadRune()
+       if r1 == '\r' {
+               r1, _, err = r.r.ReadRune()
                if err == nil {
-                       if rune != '\n' {
+                       if r1 != '\n' {
                                r.r.UnreadRune()
-                               rune = '\r'
+                               r1 = '\r'
                        }
                }
        }
        r.column++
-       return rune, err
+       return r1, err
 }
 
 // unreadRune puts the last rune read from r back.
@@ -199,13 +199,13 @@ func (r *Reader) unreadRune() {
 }
 
 // skip reads runes up to and including the rune delim or until error.
-func (r *Reader) skip(delim int) os.Error {
+func (r *Reader) skip(delim rune) os.Error {
        for {
-               rune, err := r.readRune()
+               r1, err := r.readRune()
                if err != nil {
                        return err
                }
-               if rune == delim {
+               if r1 == delim {
                        return nil
                }
        }
@@ -224,12 +224,12 @@ func (r *Reader) parseRecord() (fields []string, err os.Error) {
        // If we are support comments and it is the comment character
        // then skip to the end of line.
 
-       rune, _, err := r.r.ReadRune()
+       r1, _, err := r.r.ReadRune()
        if err != nil {
                return nil, err
        }
 
-       if r.Comment != 0 && rune == r.Comment {
+       if r.Comment != 0 && r1 == r.Comment {
                return nil, r.skip('\n')
        }
        r.r.UnreadRune()
@@ -252,10 +252,10 @@ func (r *Reader) parseRecord() (fields []string, err os.Error) {
 // parseField parses the next field in the record.  The read field is
 // located in r.field.  Delim is the first character not part of the field
 // (r.Comma or '\n').
-func (r *Reader) parseField() (haveField bool, delim int, err os.Error) {
+func (r *Reader) parseField() (haveField bool, delim rune, err os.Error) {
        r.field.Reset()
 
-       rune, err := r.readRune()
+       r1, err := r.readRune()
        if err != nil {
                // If we have EOF and are not at the start of a line
                // then we return the empty field.  We have already
@@ -267,30 +267,30 @@ func (r *Reader) parseField() (haveField bool, delim int, err os.Error) {
        }
 
        if r.TrimLeadingSpace {
-               for rune != '\n' && unicode.IsSpace(rune) {
-                       rune, err = r.readRune()
+               for r1 != '\n' && unicode.IsSpace(r1) {
+                       r1, err = r.readRune()
                        if err != nil {
                                return false, 0, err
                        }
                }
        }
 
-       switch rune {
+       switch r1 {
        case r.Comma:
                // will check below
 
        case '\n':
                // We are a trailing empty field or a blank line
                if r.column == 0 {
-                       return false, rune, nil
+                       return false, r1, nil
                }
-               return true, rune, nil
+               return true, r1, nil
 
        case '"':
                // quoted field
        Quoted:
                for {
-                       rune, err = r.readRune()
+                       r1, err = r.readRune()
                        if err != nil {
                                if err == os.EOF {
                                        if r.LazyQuotes {
@@ -300,16 +300,16 @@ func (r *Reader) parseField() (haveField bool, delim int, err os.Error) {
                                }
                                return false, 0, err
                        }
-                       switch rune {
+                       switch r1 {
                        case '"':
-                               rune, err = r.readRune()
-                               if err != nil || rune == r.Comma {
+                               r1, err = r.readRune()
+                               if err != nil || r1 == r.Comma {
                                        break Quoted
                                }
-                               if rune == '\n' {
-                                       return true, rune, nil
+                               if r1 == '\n' {
+                                       return true, r1, nil
                                }
-                               if rune != '"' {
+                               if r1 != '"' {
                                        if !r.LazyQuotes {
                                                r.column--
                                                return false, 0, r.error(ErrQuote)
@@ -321,21 +321,21 @@ func (r *Reader) parseField() (haveField bool, delim int, err os.Error) {
                                r.line++
                                r.column = -1
                        }
-                       r.field.WriteRune(rune)
+                       r.field.WriteRune(r1)
                }
 
        default:
                // unquoted field
                for {
-                       r.field.WriteRune(rune)
-                       rune, err = r.readRune()
-                       if err != nil || rune == r.Comma {
+                       r.field.WriteRune(r1)
+                       r1, err = r.readRune()
+                       if err != nil || r1 == r.Comma {
                                break
                        }
-                       if rune == '\n' {
-                               return true, rune, nil
+                       if r1 == '\n' {
+                               return true, r1, nil
                        }
-                       if !r.LazyQuotes && rune == '"' {
+                       if !r.LazyQuotes && r1 == '"' {
                                return false, 0, r.error(ErrBareQuote)
                        }
                }
@@ -353,20 +353,20 @@ func (r *Reader) parseField() (haveField bool, delim int, err os.Error) {
                // are at the end of the line (being mindful
                // of trimming spaces).
                c := r.column
-               rune, err = r.readRune()
+               r1, err = r.readRune()
                if r.TrimLeadingSpace {
-                       for rune != '\n' && unicode.IsSpace(rune) {
-                               rune, err = r.readRune()
+                       for r1 != '\n' && unicode.IsSpace(r1) {
+                               r1, err = r.readRune()
                                if err != nil {
                                        break
                                }
                        }
                }
-               if err == os.EOF || rune == '\n' {
+               if err == os.EOF || r1 == '\n' {
                        r.column = c // report the comma
                        return false, 0, r.error(ErrTrailingComma)
                }
                r.unreadRune()
        }
-       return true, rune, nil
+       return true, r1, nil
 }
index 967f96b..1b23605 100644 (file)
@@ -17,8 +17,8 @@ var readTests = []struct {
        UseFieldsPerRecord bool // false (default) means FieldsPerRecord is -1
 
        // These fields are copied into the Reader
-       Comma            int
-       Comment          int
+       Comma            rune
+       Comment          rune
        FieldsPerRecord  int
        LazyQuotes       bool
        TrailingComma    bool
index ccf703f..98573c2 100644 (file)
@@ -23,7 +23,7 @@ import (
 //
 // If UseCRLF is true, the Writer ends each record with \r\n instead of \n.
 type Writer struct {
-       Comma   int  // Field delimiter (set to to ',' by NewWriter)
+       Comma   rune // Field delimiter (set to to ',' by NewWriter)
        UseCRLF bool // True to use \r\n as the line terminator
        w       *bufio.Writer
 }
@@ -58,8 +58,8 @@ func (w *Writer) Write(record []string) (err os.Error) {
                        return
                }
 
-               for _, rune := range field {
-                       switch rune {
+               for _, r1 := range field {
+                       switch r1 {
                        case '"':
                                _, err = w.w.WriteString(`""`)
                        case '\r':
@@ -73,7 +73,7 @@ func (w *Writer) Write(record []string) (err os.Error) {
                                        err = w.w.WriteByte('\n')
                                }
                        default:
-                               _, err = w.w.WriteRune(rune)
+                               _, err = w.w.WriteRune(r1)
                        }
                        if err != nil {
                                return
@@ -117,6 +117,6 @@ func (w *Writer) fieldNeedsQuotes(field string) bool {
                return true
        }
 
-       rune, _ := utf8.DecodeRuneInString(field)
-       return unicode.IsSpace(rune)
+       r1, _ := utf8.DecodeRuneInString(field)
+       return unicode.IsSpace(r1)
 }
index b266996..ef20605 100644 (file)
@@ -5,10 +5,10 @@
 package binary
 
 import (
-       "io"
-       "os"
        "bytes"
+       "io"
        "math"
+       "os"
        "reflect"
        "testing"
 )
@@ -99,7 +99,7 @@ var little = []byte{
 var src = []byte{1, 2, 3, 4, 5, 6, 7, 8}
 var res = []int32{0x01020304, 0x05060708}
 
-func checkResult(t *testing.T, dir string, order, err os.Error, have, want interface{}) {
+func checkResult(t *testing.T, dir string, order ByteOrder, err os.Error, have, want interface{}) {
        if err != nil {
                t.Errorf("%v %v: %v", dir, order, err)
                return
index 2ec7f00..7070cc7 100644 (file)
@@ -163,7 +163,7 @@ func (v *verifier) push(prod *Production) {
        }
 }
 
-func (v *verifier) verifyChar(x *Token) int {
+func (v *verifier) verifyChar(x *Token) rune {
        s := x.String
        if utf8.RuneCountInString(s) != 1 {
                v.error(x.Pos(), "single char expected, found "+s)
index 2dbbefb..dac5dd8 100644 (file)
@@ -15,7 +15,7 @@ type parser struct {
        errors  errorList
        scanner scanner.Scanner
        pos     scanner.Position // token position
-       tok     int              // one token look-ahead
+       tok     rune             // one token look-ahead
        lit     string           // token literal
 }
 
@@ -42,7 +42,7 @@ func (p *parser) errorExpected(pos scanner.Position, msg string) {
        p.error(pos, msg)
 }
 
-func (p *parser) expect(tok int) scanner.Position {
+func (p *parser) expect(tok rune) scanner.Position {
        pos := p.pos
        if p.tok != tok {
                p.errorExpected(pos, scanner.TokenString(tok))
index bf94bca..f4a453e 100644 (file)
@@ -87,7 +87,7 @@ func (c *conn) writeSocket() {
                        setU32LE(c.flushBuf0[16:20], uint32(y<<16))
                        if _, err := c.w.Write(c.flushBuf0[:24]); err != nil {
                                if err != os.EOF {
-                                       log.Println("x11:", err.String())
+                                       log.Println("x11:", err)
                                }
                                return
                        }
@@ -106,7 +106,7 @@ func (c *conn) writeSocket() {
                                x += nx
                                if _, err := c.w.Write(c.flushBuf1[:nx]); err != nil {
                                        if err != os.EOF {
-                                               log.Println("x11:", err.String())
+                                               log.Println("x11:", err)
                                        }
                                        return
                                }
@@ -114,7 +114,7 @@ func (c *conn) writeSocket() {
                }
                if err := c.w.Flush(); err != nil {
                        if err != os.EOF {
-                               log.Println("x11:", err.String())
+                               log.Println("x11:", err)
                        }
                        return
                }
index 1d72223..7965ffc 100644 (file)
@@ -126,26 +126,26 @@ func (rb *reorderBuffer) insert(src input, i int, info runeInfo) bool {
 }
 
 // appendRune inserts a rune at the end of the buffer. It is used for Hangul.
-func (rb *reorderBuffer) appendRune(rune uint32) {
+func (rb *reorderBuffer) appendRune(r uint32) {
        bn := rb.nbyte
-       sz := utf8.EncodeRune(rb.byte[bn:], int(rune))
+       sz := utf8.EncodeRune(rb.byte[bn:], rune(r))
        rb.nbyte += utf8.UTFMax
        rb.rune[rb.nrune] = runeInfo{bn, uint8(sz), 0, 0}
        rb.nrune++
 }
 
 // assignRune sets a rune at position pos. It is used for Hangul and recomposition.
-func (rb *reorderBuffer) assignRune(pos int, rune uint32) {
+func (rb *reorderBuffer) assignRune(pos int, r uint32) {
        bn := rb.rune[pos].pos
-       sz := utf8.EncodeRune(rb.byte[bn:], int(rune))
+       sz := utf8.EncodeRune(rb.byte[bn:], rune(r))
        rb.rune[pos] = runeInfo{bn, uint8(sz), 0, 0}
 }
 
 // runeAt returns the rune at position n. It is used for Hangul and recomposition.
 func (rb *reorderBuffer) runeAt(n int) uint32 {
        inf := rb.rune[n]
-       rune, _ := utf8.DecodeRune(rb.byte[inf.pos : inf.pos+inf.size])
-       return uint32(rune)
+       r, _ := utf8.DecodeRune(rb.byte[inf.pos : inf.pos+inf.size])
+       return uint32(r)
 }
 
 // bytesAt returns the UTF-8 encoding of the rune at position n.
@@ -237,17 +237,17 @@ func isHangulWithoutJamoT(b []byte) bool {
 // decomposeHangul algorithmically decomposes a Hangul rune into
 // its Jamo components.
 // See http://unicode.org/reports/tr15/#Hangul for details on decomposing Hangul.
-func (rb *reorderBuffer) decomposeHangul(rune uint32) bool {
+func (rb *reorderBuffer) decomposeHangul(r uint32) bool {
        b := rb.rune[:]
        n := rb.nrune
        if n+3 > len(b) {
                return false
        }
-       rune -= hangulBase
-       x := rune % jamoTCount
-       rune /= jamoTCount
-       rb.appendRune(jamoLBase + rune/jamoVCount)
-       rb.appendRune(jamoVBase + rune%jamoVCount)
+       r -= hangulBase
+       x := r % jamoTCount
+       r /= jamoTCount
+       rb.appendRune(jamoLBase + r/jamoVCount)
+       rb.appendRune(jamoVBase + r%jamoVCount)
        if x != 0 {
                rb.appendRune(jamoTBase + x)
        }
index ce9caaf..e32380d 100644 (file)
@@ -8,14 +8,14 @@ import "testing"
 
 // TestCase is used for most tests.
 type TestCase struct {
-       in  []int
-       out []int
+       in  []rune
+       out []rune
 }
 
-type insertFunc func(rb *reorderBuffer, rune int) bool
+type insertFunc func(rb *reorderBuffer, r rune) bool
 
-func insert(rb *reorderBuffer, rune int) bool {
-       src := inputString(string(rune))
+func insert(rb *reorderBuffer, r rune) bool {
+       src := inputString(string(r))
        return rb.insert(src, 0, rb.f.info(src, 0))
 }
 
@@ -39,7 +39,7 @@ func runTests(t *testing.T, name string, fm Form, f insertFunc, tests []TestCase
                        continue
                }
                for j, want := range test.out {
-                       found := int(rb.runeAt(j))
+                       found := rune(rb.runeAt(j))
                        if found != want {
                                t.Errorf("%s:%d: runeAt(%d) = %U; want %U", name, i, j, found, want)
                        }
@@ -57,7 +57,7 @@ func TestFlush(t *testing.T) {
                t.Errorf("wrote bytes on flush of empty buffer. (len(out) = %d)", len(out))
        }
 
-       for _, r := range []int("world!") {
+       for _, r := range []rune("world!") {
                insert(&rb, r)
        }
 
@@ -76,14 +76,14 @@ func TestFlush(t *testing.T) {
 }
 
 var insertTests = []TestCase{
-       {[]int{'a'}, []int{'a'}},
-       {[]int{0x300}, []int{0x300}},
-       {[]int{0x300, 0x316}, []int{0x316, 0x300}}, // CCC(0x300)==230; CCC(0x316)==220
-       {[]int{0x316, 0x300}, []int{0x316, 0x300}},
-       {[]int{0x41, 0x316, 0x300}, []int{0x41, 0x316, 0x300}},
-       {[]int{0x41, 0x300, 0x316}, []int{0x41, 0x316, 0x300}},
-       {[]int{0x300, 0x316, 0x41}, []int{0x316, 0x300, 0x41}},
-       {[]int{0x41, 0x300, 0x40, 0x316}, []int{0x41, 0x300, 0x40, 0x316}},
+       {[]rune{'a'}, []rune{'a'}},
+       {[]rune{0x300}, []rune{0x300}},
+       {[]rune{0x300, 0x316}, []rune{0x316, 0x300}}, // CCC(0x300)==230; CCC(0x316)==220
+       {[]rune{0x316, 0x300}, []rune{0x316, 0x300}},
+       {[]rune{0x41, 0x316, 0x300}, []rune{0x41, 0x316, 0x300}},
+       {[]rune{0x41, 0x300, 0x316}, []rune{0x41, 0x316, 0x300}},
+       {[]rune{0x300, 0x316, 0x41}, []rune{0x316, 0x300, 0x41}},
+       {[]rune{0x41, 0x300, 0x40, 0x316}, []rune{0x41, 0x300, 0x40, 0x316}},
 }
 
 func TestInsert(t *testing.T) {
@@ -91,18 +91,18 @@ func TestInsert(t *testing.T) {
 }
 
 var decompositionNFDTest = []TestCase{
-       {[]int{0xC0}, []int{0x41, 0x300}},
-       {[]int{0xAC00}, []int{0x1100, 0x1161}},
-       {[]int{0x01C4}, []int{0x01C4}},
-       {[]int{0x320E}, []int{0x320E}},
-       {[]int("음ẻ과"), []int{0x110B, 0x1173, 0x11B7, 0x65, 0x309, 0x1100, 0x116A}},
+       {[]rune{0xC0}, []rune{0x41, 0x300}},
+       {[]rune{0xAC00}, []rune{0x1100, 0x1161}},
+       {[]rune{0x01C4}, []rune{0x01C4}},
+       {[]rune{0x320E}, []rune{0x320E}},
+       {[]rune("음ẻ과"), []rune{0x110B, 0x1173, 0x11B7, 0x65, 0x309, 0x1100, 0x116A}},
 }
 
 var decompositionNFKDTest = []TestCase{
-       {[]int{0xC0}, []int{0x41, 0x300}},
-       {[]int{0xAC00}, []int{0x1100, 0x1161}},
-       {[]int{0x01C4}, []int{0x44, 0x5A, 0x030C}},
-       {[]int{0x320E}, []int{0x28, 0x1100, 0x1161, 0x29}},
+       {[]rune{0xC0}, []rune{0x41, 0x300}},
+       {[]rune{0xAC00}, []rune{0x1100, 0x1161}},
+       {[]rune{0x01C4}, []rune{0x44, 0x5A, 0x030C}},
+       {[]rune{0x320E}, []rune{0x28, 0x1100, 0x1161, 0x29}},
 }
 
 func TestDecomposition(t *testing.T) {
@@ -111,15 +111,15 @@ func TestDecomposition(t *testing.T) {
 }
 
 var compositionTest = []TestCase{
-       {[]int{0x41, 0x300}, []int{0xC0}},
-       {[]int{0x41, 0x316}, []int{0x41, 0x316}},
-       {[]int{0x41, 0x300, 0x35D}, []int{0xC0, 0x35D}},
-       {[]int{0x41, 0x316, 0x300}, []int{0xC0, 0x316}},
+       {[]rune{0x41, 0x300}, []rune{0xC0}},
+       {[]rune{0x41, 0x316}, []rune{0x41, 0x316}},
+       {[]rune{0x41, 0x300, 0x35D}, []rune{0xC0, 0x35D}},
+       {[]rune{0x41, 0x316, 0x300}, []rune{0xC0, 0x316}},
        // blocking starter
-       {[]int{0x41, 0x316, 0x40, 0x300}, []int{0x41, 0x316, 0x40, 0x300}},
-       {[]int{0x1100, 0x1161}, []int{0xAC00}},
+       {[]rune{0x41, 0x316, 0x40, 0x300}, []rune{0x41, 0x316, 0x40, 0x300}},
+       {[]rune{0x1100, 0x1161}, []rune{0xAC00}},
        // parenthesized Hangul, alternate between ASCII and Hangul.
-       {[]int{0x28, 0x1100, 0x1161, 0x29}, []int{0x28, 0xAC00, 0x29}},
+       {[]rune{0x28, 0x1100, 0x1161, 0x29}, []rune{0x28, 0xAC00, 0x29}},
 }
 
 func TestComposition(t *testing.T) {
index 14718c5..93edf22 100644 (file)
@@ -119,7 +119,7 @@ const (
 // This contains only the properties we're interested in.
 type Char struct {
        name          string
-       codePoint     int   // if zero, this index is not a valid code point.
+       codePoint     rune  // if zero, this index is not a valid code point.
        ccc           uint8 // canonical combining class
        excludeInComp bool  // from CompositionExclusions.txt
        compatDecomp  bool  // it has a compatibility expansion
@@ -160,7 +160,7 @@ const (
        SMissing
 )
 
-var lastChar int = 0
+var lastChar = rune('\u0000')
 
 func (c Char) isValid() bool {
        return c.codePoint != 0 && c.state != SMissing
@@ -193,7 +193,7 @@ func (f FormInfo) String() string {
        return buf.String()
 }
 
-type Decomposition []int
+type Decomposition []rune
 
 func (d Decomposition) String() string {
        return fmt.Sprintf("%.4X", d)
@@ -220,7 +220,7 @@ func openReader(file string) (input io.ReadCloser) {
        return
 }
 
-func parseDecomposition(s string, skipfirst bool) (a []int, e os.Error) {
+func parseDecomposition(s string, skipfirst bool) (a []rune, e os.Error) {
        decomp := strings.Split(s, " ")
        if len(decomp) > 0 && skipfirst {
                decomp = decomp[1:]
@@ -230,7 +230,7 @@ func parseDecomposition(s string, skipfirst bool) (a []int, e os.Error) {
                if err != nil {
                        return a, err
                }
-               a = append(a, int(point))
+               a = append(a, rune(point))
        }
        return a, nil
 }
@@ -260,7 +260,7 @@ func parseCharacter(line string) {
                state = SLast
        }
        firstChar := lastChar + 1
-       lastChar = int(point)
+       lastChar = rune(point)
        if state != SLast {
                firstChar = lastChar
        }
@@ -370,8 +370,8 @@ func loadCompositionExclusions() {
 // hasCompatDecomp returns true if any of the recursive
 // decompositions contains a compatibility expansion.
 // In this case, the character may not occur in NFK*.
-func hasCompatDecomp(rune int) bool {
-       c := &chars[rune]
+func hasCompatDecomp(r rune) bool {
+       c := &chars[r]
        if c.compatDecomp {
                return true
        }
@@ -396,19 +396,19 @@ const (
        JamoTEnd  = 0x11C3
 )
 
-func isHangul(rune int) bool {
-       return HangulBase <= rune && rune < HangulEnd
+func isHangul(r rune) bool {
+       return HangulBase <= r && r < HangulEnd
 }
 
-func ccc(rune int) uint8 {
-       return chars[rune].ccc
+func ccc(r rune) uint8 {
+       return chars[r].ccc
 }
 
 // Insert a rune in a buffer, ordered by Canonical Combining Class.
-func insertOrdered(b Decomposition, rune int) Decomposition {
+func insertOrdered(b Decomposition, r rune) Decomposition {
        n := len(b)
        b = append(b, 0)
-       cc := ccc(rune)
+       cc := ccc(r)
        if cc > 0 {
                // Use bubble sort.
                for ; n > 0; n-- {
@@ -418,18 +418,18 @@ func insertOrdered(b Decomposition, rune int) Decomposition {
                        b[n] = b[n-1]
                }
        }
-       b[n] = rune
+       b[n] = r
        return b
 }
 
 // Recursively decompose.
-func decomposeRecursive(form int, rune int, d Decomposition) Decomposition {
-       if isHangul(rune) {
+func decomposeRecursive(form int, r rune, d Decomposition) Decomposition {
+       if isHangul(r) {
                return d
        }
-       dcomp := chars[rune].forms[form].decomp
+       dcomp := chars[r].forms[form].decomp
        if len(dcomp) == 0 {
-               return insertOrdered(d, rune)
+               return insertOrdered(d, r)
        }
        for _, c := range dcomp {
                d = decomposeRecursive(form, c, d)
@@ -475,8 +475,8 @@ func completeCharFields(form int) {
                        f.isOneWay = f.isOneWay || hasCompatDecomp(c.codePoint)
                }
 
-               for _, rune := range f.decomp {
-                       chars[rune].forms[form].inDecomp = true
+               for _, r := range f.decomp {
+                       chars[r].forms[form].inDecomp = true
                }
        }
 
@@ -505,7 +505,7 @@ func completeCharFields(form int) {
                switch {
                case len(f.decomp) > 0:
                        f.quickCheck[MDecomposed] = QCNo
-               case isHangul(i):
+               case isHangul(rune(i)):
                        f.quickCheck[MDecomposed] = QCNo
                default:
                        f.quickCheck[MDecomposed] = QCYes
@@ -588,7 +588,7 @@ func printCharInfoTables() int {
        for i, char := range chars {
                v := makeCharInfo(char)
                if v != 0 {
-                       t.insert(i, v)
+                       t.insert(rune(i), v)
                }
        }
        return t.printTables("charInfo")
@@ -606,7 +606,7 @@ func printDecompositionTables() int {
        for _, c := range chars {
                for f := 0; f < 2; f++ {
                        d := c.forms[f].expandedDecomp
-                       s := string([]int(d))
+                       s := string([]rune(d))
                        if _, ok := positionMap[s]; !ok {
                                p := decompositions.Len()
                                decompositions.WriteByte(uint8(len(s)))
@@ -624,7 +624,7 @@ func printDecompositionTables() int {
        for i, c := range chars {
                d := c.forms[FCanonical].expandedDecomp
                if len(d) != 0 {
-                       nfcT.insert(i, positionMap[string([]int(d))])
+                       nfcT.insert(rune(i), positionMap[string([]rune(d))])
                        if ccc(c.codePoint) != ccc(d[0]) {
                                // We assume the lead ccc of a decomposition is !=0 in this case.
                                if ccc(d[0]) == 0 {
@@ -634,7 +634,7 @@ func printDecompositionTables() int {
                }
                d = c.forms[FCompatibility].expandedDecomp
                if len(d) != 0 {
-                       nfkcT.insert(i, positionMap[string([]int(d))])
+                       nfkcT.insert(rune(i), positionMap[string([]rune(d))])
                        if ccc(c.codePoint) != ccc(d[0]) {
                                // We assume the lead ccc of a decomposition is !=0 in this case.
                                if ccc(d[0]) == 0 {
@@ -752,7 +752,7 @@ func verifyComputed() {
        for i, c := range chars {
                for _, f := range c.forms {
                        isNo := (f.quickCheck[MDecomposed] == QCNo)
-                       if (len(f.decomp) > 0) != isNo && !isHangul(i) {
+                       if (len(f.decomp) > 0) != isNo && !isHangul(rune(i)) {
                                log.Fatalf("%U: NF*D must be no if rune decomposes", i)
                        }
 
@@ -764,7 +764,7 @@ func verifyComputed() {
        }
 }
 
-var qcRe = regexp.MustCompile(`^([0-9A-F\.]+) *; (NF.*_QC); ([YNM]) #.*$`)
+var qcRe = regexp.MustCompile(`([0-9A-F\.]+) *; (NF.*_QC); ([YNM]) #.*`)
 
 // Use values in DerivedNormalizationProps.txt to compare against the
 // values we computed.
index fdcc114..20eb889 100644 (file)
@@ -16,7 +16,7 @@ func main() {
 
 // We take the smallest, largest and an arbitrary value for each 
 // of the UTF-8 sequence lengths.
-var testRunes = []int{
+var testRunes = []rune{
        0x01, 0x0C, 0x7F, // 1-byte sequences
        0x80, 0x100, 0x7FF, // 2-byte sequences
        0x800, 0x999, 0xFFFF, // 3-byte sequences
index e374edf..6bd5292 100644 (file)
@@ -28,13 +28,13 @@ func runPosTests(t *testing.T, name string, f Form, fn positionFunc, tests []Pos
                if pos != test.pos {
                        t.Errorf("%s:%d: position is %d; want %d", name, i, pos, test.pos)
                }
-               runes := []int(test.buffer)
+               runes := []rune(test.buffer)
                if rb.nrune != len(runes) {
                        t.Errorf("%s:%d: reorder buffer lenght is %d; want %d", name, i, rb.nrune, len(runes))
                        continue
                }
                for j, want := range runes {
-                       found := int(rb.runeAt(j))
+                       found := rune(rb.runeAt(j))
                        if found != want {
                                t.Errorf("%s:%d: rune at %d is %U; want %U", name, i, j, found, want)
                        }
@@ -385,8 +385,8 @@ func runAppendTests(t *testing.T, name string, f Form, fn appendFunc, tests []Ap
                }
                if outs != test.out {
                        // Find first rune that differs and show context.
-                       ir := []int(outs)
-                       ig := []int(test.out)
+                       ir := []rune(outs)
+                       ig := []rune(test.out)
                        for j := 0; j < len(ir) && j < len(ig); j++ {
                                if ir[j] == ig[j] {
                                        continue
index cbd73ff..e747dde 100644 (file)
@@ -16,8 +16,8 @@ import (
        "path"
        "regexp"
        "runtime"
-       "strings"
        "strconv"
+       "strings"
        "time"
        "utf8"
 )
@@ -103,7 +103,7 @@ type Test struct {
        name   string
        partnr int
        number int
-       rune   int                 // used for character by character test
+       r      rune                // used for character by character test
        cols   [cMaxColumns]string // Each has 5 entries, see below.
 }
 
@@ -174,12 +174,12 @@ func loadTestData() {
                                if err != nil {
                                        logger.Fatal(err)
                                }
-                               if test.rune == 0 {
+                               if test.r == 0 {
                                        // save for CharacterByCharacterTests
-                                       test.rune = int(r)
+                                       test.r = int(r)
                                }
                                var buf [utf8.UTFMax]byte
-                               sz := utf8.EncodeRune(buf[:], int(r))
+                               sz := utf8.EncodeRune(buf[:], rune(r))
                                test.cols[j-1] += string(buf[:sz])
                        }
                }
@@ -198,7 +198,7 @@ func cmpResult(t *Test, name string, f norm.Form, gold, test, result string) {
                if errorCount > 20 {
                        return
                }
-               st, sr, sg := []int(test), []int(result), []int(gold)
+               st, sr, sg := []rune(test), []rune(result), []rune(gold)
                logger.Printf("%s:%s: %s(%X)=%X; want:%X: %s",
                        t.Name(), name, fstr[f], st, sr, sg, t.name)
        }
@@ -210,7 +210,7 @@ func cmpIsNormal(t *Test, name string, f norm.Form, test string, result, want bo
                if errorCount > 20 {
                        return
                }
-               logger.Printf("%s:%s: %s(%X)=%v; want: %v", t.Name(), name, fstr[f], []int(test), result, want)
+               logger.Printf("%s:%s: %s(%X)=%v; want: %v", t.Name(), name, fstr[f], []rune(test), result, want)
        }
 }
 
@@ -243,13 +243,13 @@ func CharacterByCharacterTests() {
        tests := part[1].tests
        last := 0
        for i := 0; i <= len(tests); i++ { // last one is special case
-               var rune int
+               var r int
                if i == len(tests) {
-                       rune = 0x2FA1E // Don't have to go to 0x10FFFF
+                       r = 0x2FA1E // Don't have to go to 0x10FFFF
                } else {
-                       rune = tests[i].rune
+                       r = tests[i].r
                }
-               for last++; last < rune; last++ {
+               for last++; last < r; last++ {
                        // Check all characters that were not explicitly listed in the test.
                        t := &Test{partnr: 1, number: -1}
                        char := string(last)
index 5649fb7..bbd5c03 100644 (file)
@@ -73,15 +73,15 @@ var tests = []trietest{
        {1, []byte{t6, tx, tx, tx, tx, tx}},
 }
 
-func mkUtf8(rune int) ([]byte, int) {
+func mkUTF8(r rune) ([]byte, int) {
        var b [utf8.UTFMax]byte
-       sz := utf8.EncodeRune(b[:], rune)
+       sz := utf8.EncodeRune(b[:], r)
        return b[:sz], sz
 }
 
 func TestLookup(t *testing.T) {
        for i, tt := range testRunes {
-               b, szg := mkUtf8(tt)
+               b, szg := mkUTF8(tt)
                v, szt := testdata.lookup(b)
                if int(v) != i {
                        t.Errorf("lookup(%U): found value %#x, expected %#x", tt, v, i)
@@ -103,7 +103,7 @@ func TestLookup(t *testing.T) {
 
 func TestLookupUnsafe(t *testing.T) {
        for i, tt := range testRunes {
-               b, _ := mkUtf8(tt)
+               b, _ := mkUTF8(tt)
                v := testdata.lookupUnsafe(b)
                if int(v) != i {
                        t.Errorf("lookupUnsafe(%U): found value %#x, expected %#x", i, v, i)
@@ -113,7 +113,7 @@ func TestLookupUnsafe(t *testing.T) {
 
 func TestLookupString(t *testing.T) {
        for i, tt := range testRunes {
-               b, szg := mkUtf8(tt)
+               b, szg := mkUTF8(tt)
                v, szt := testdata.lookupString(string(b))
                if int(v) != i {
                        t.Errorf("lookup(%U): found value %#x, expected %#x", i, v, i)
@@ -135,7 +135,7 @@ func TestLookupString(t *testing.T) {
 
 func TestLookupStringUnsafe(t *testing.T) {
        for i, tt := range testRunes {
-               b, _ := mkUtf8(tt)
+               b, _ := mkUTF8(tt)
                v := testdata.lookupStringUnsafe(string(b))
                if int(v) != i {
                        t.Errorf("lookupUnsafe(%U): found value %#x, expected %#x", i, v, i)
index e8898e5..7f62760 100644 (file)
@@ -4,7 +4,7 @@
 
 package norm
 
-var testRunes = []int{1, 12, 127, 128, 256, 2047, 2048, 2457, 65535, 65536, 65793, 1114111, 512, 513, 514, 528, 533}
+var testRunes = []rune{1, 12, 127, 128, 256, 2047, 2048, 2457, 65535, 65536, 65793, 1114111, 512, 513, 514, 528, 533}
 
 // testdataValues: 192 entries, 384 bytes
 // Block 2 is the null block.
index 515e1c7..56cba32 100644 (file)
@@ -94,9 +94,9 @@ func (n trieNode) countSparseEntries() int {
        return count
 }
 
-func (n *trieNode) insert(rune int, value uint16) {
+func (n *trieNode) insert(r rune, value uint16) {
        var p [utf8.UTFMax]byte
-       sz := utf8.EncodeRune(p[:], rune)
+       sz := utf8.EncodeRune(p[:], r)
 
        for i := 0; i < sz; i++ {
                if n.leaf {
index 88ba8e7..8499918 100644 (file)
@@ -52,7 +52,7 @@ var conversionTests = []conversionTest{
        {s: "256", d: &scanuint8, wanterr: `string "256" overflows uint8`},
        {s: "256", d: &scanuint16, wantuint: 256},
        {s: "-1", d: &scanint, wantint: -1},
-       {s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: parsing "foo": Invalid argument`},
+       {s: "foo", d: &scanint, wanterr: `converting string "foo" to a int: parsing "foo": invalid syntax`},
 }
 
 func intValue(intptr interface{}) int64 {
index 3311385..9eed315 100644 (file)
@@ -258,51 +258,71 @@ func (c *ClientConn) openChan(typ string) (*clientChan, os.Error) {
 // mainloop reads incoming messages and routes channel messages
 // to their respective ClientChans.
 func (c *ClientConn) mainLoop() {
+       // TODO(dfc) signal the underlying close to all channels
+       defer c.Close()
        for {
                packet, err := c.readPacket()
                if err != nil {
-                       // TODO(dfc) signal the underlying close to all channels
-                       c.Close()
-                       return
+                       break
                }
                // TODO(dfc) A note on blocking channel use. 
                // The msg, win, data and dataExt channels of a clientChan can 
                // cause this loop to block indefinately if the consumer does 
                // not service them. 
-               switch msg := decode(packet).(type) {
-               case *channelOpenMsg:
-                       c.getChan(msg.PeersId).msg <- msg
-               case *channelOpenConfirmMsg:
-                       c.getChan(msg.PeersId).msg <- msg
-               case *channelOpenFailureMsg:
-                       c.getChan(msg.PeersId).msg <- msg
-               case *channelCloseMsg:
-                       ch := c.getChan(msg.PeersId)
-                       close(ch.win)
-                       close(ch.data)
-                       close(ch.dataExt)
-                       c.chanlist.remove(msg.PeersId)
-               case *channelEOFMsg:
-                       c.getChan(msg.PeersId).msg <- msg
-               case *channelRequestSuccessMsg:
-                       c.getChan(msg.PeersId).msg <- msg
-               case *channelRequestFailureMsg:
-                       c.getChan(msg.PeersId).msg <- msg
-               case *channelRequestMsg:
-                       c.getChan(msg.PeersId).msg <- msg
-               case *windowAdjustMsg:
-                       c.getChan(msg.PeersId).win <- int(msg.AdditionalBytes)
-               case *channelData:
-                       c.getChan(msg.PeersId).data <- msg.Payload
-               case *channelExtendedData:
-                       // RFC 4254 5.2 defines data_type_code 1 to be data destined 
-                       // for stderr on interactive sessions. Other data types are
-                       // silently discarded.
-                       if msg.Datatype == 1 {
-                               c.getChan(msg.PeersId).dataExt <- msg.Payload
+               switch packet[0] {
+               case msgChannelData:
+                       if len(packet) < 9 {
+                               // malformed data packet
+                               break
+                       }
+                       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]
+                       }
+               case msgChannelExtendedData:
+                       if len(packet) < 13 {
+                               // malformed data packet
+                               break
+                       }
+                       peersId := uint32(packet[1])<<24 | uint32(packet[2])<<16 | uint32(packet[3])<<8 | uint32(packet[4])
+                       datatype := uint32(packet[5])<<24 | uint32(packet[6])<<16 | uint32(packet[7])<<8 | uint32(packet[8])
+                       if length := int(packet[9])<<24 | int(packet[10])<<16 | int(packet[11])<<8 | int(packet[12]); length > 0 {
+                               packet = packet[13:]
+                               // RFC 4254 5.2 defines data_type_code 1 to be data destined 
+                               // for stderr on interactive sessions. Other data types are
+                               // silently discarded.
+                               if datatype == 1 {
+                                       c.getChan(peersId).dataExt <- packet[:length]
+                               }
                        }
                default:
-                       fmt.Printf("mainLoop: unhandled %#v\n", msg)
+                       switch msg := decode(packet).(type) {
+                       case *channelOpenMsg:
+                               c.getChan(msg.PeersId).msg <- msg
+                       case *channelOpenConfirmMsg:
+                               c.getChan(msg.PeersId).msg <- msg
+                       case *channelOpenFailureMsg:
+                               c.getChan(msg.PeersId).msg <- msg
+                       case *channelCloseMsg:
+                               ch := c.getChan(msg.PeersId)
+                               close(ch.win)
+                               close(ch.data)
+                               close(ch.dataExt)
+                               c.chanlist.remove(msg.PeersId)
+                       case *channelEOFMsg:
+                               c.getChan(msg.PeersId).msg <- msg
+                       case *channelRequestSuccessMsg:
+                               c.getChan(msg.PeersId).msg <- msg
+                       case *channelRequestFailureMsg:
+                               c.getChan(msg.PeersId).msg <- msg
+                       case *channelRequestMsg:
+                               c.getChan(msg.PeersId).msg <- msg
+                       case *windowAdjustMsg:
+                               c.getChan(msg.PeersId).win <- int(msg.AdditionalBytes)
+                       default:
+                               fmt.Printf("mainLoop: unhandled %#v\n", msg)
+                       }
                }
        }
 }
index 7771f2b..5f2c447 100644 (file)
@@ -144,19 +144,6 @@ type channelOpenFailureMsg struct {
        Language string
 }
 
-// See RFC 4254, section 5.2.
-type channelData struct {
-       PeersId uint32
-       Payload []byte `ssh:"rest"`
-}
-
-// See RFC 4254, section 5.2.
-type channelExtendedData struct {
-       PeersId  uint32
-       Datatype uint32
-       Payload  []byte `ssh:"rest"`
-}
-
 type channelRequestMsg struct {
        PeersId             uint32
        Request             string
@@ -612,10 +599,6 @@ func decode(packet []byte) interface{} {
                msg = new(channelOpenFailureMsg)
        case msgChannelWindowAdjust:
                msg = new(windowAdjustMsg)
-       case msgChannelData:
-               msg = new(channelData)
-       case msgChannelExtendedData:
-               msg = new(channelExtendedData)
        case msgChannelEOF:
                msg = new(channelEOFMsg)
        case msgChannelClose:
index 3a640fc..0dd24ec 100644 (file)
@@ -581,75 +581,89 @@ func (s *ServerConn) Accept() (Channel, os.Error) {
                        return nil, err
                }
 
-               switch msg := decode(packet).(type) {
-               case *channelOpenMsg:
-                       c := new(channel)
-                       c.chanType = msg.ChanType
-                       c.theirId = msg.PeersId
-                       c.theirWindow = msg.PeersWindow
-                       c.maxPacketSize = msg.MaxPacketSize
-                       c.extraData = msg.TypeSpecificData
-                       c.myWindow = defaultWindowSize
-                       c.serverConn = s
-                       c.cond = sync.NewCond(&c.lock)
-                       c.pendingData = make([]byte, c.myWindow)
-
-                       s.lock.Lock()
-                       c.myId = s.nextChanId
-                       s.nextChanId++
-                       s.channels[c.myId] = c
-                       s.lock.Unlock()
-                       return c, nil
-
-               case *channelRequestMsg:
-                       s.lock.Lock()
-                       c, ok := s.channels[msg.PeersId]
-                       if !ok {
-                               continue
+               switch packet[0] {
+               case msgChannelData:
+                       if len(packet) < 9 {
+                               // malformed data packet
+                               return nil, ParseError{msgChannelData}
                        }
-                       c.handlePacket(msg)
-                       s.lock.Unlock()
-
-               case *channelData:
+                       peersId := uint32(packet[1])<<24 | uint32(packet[2])<<16 | uint32(packet[3])<<8 | uint32(packet[4])
                        s.lock.Lock()
-                       c, ok := s.channels[msg.PeersId]
+                       c, ok := s.channels[peersId]
                        if !ok {
+                               s.lock.Unlock()
                                continue
                        }
-                       c.handleData(msg.Payload)
-                       s.lock.Unlock()
-
-               case *channelEOFMsg:
-                       s.lock.Lock()
-                       c, ok := s.channels[msg.PeersId]
-                       if !ok {
-                               continue
+                       if length := int(packet[5])<<24 | int(packet[6])<<16 | int(packet[7])<<8 | int(packet[8]); length > 0 {
+                               packet = packet[9:]
+                               c.handleData(packet[:length])
                        }
-                       c.handlePacket(msg)
                        s.lock.Unlock()
+               default:
+                       switch msg := decode(packet).(type) {
+                       case *channelOpenMsg:
+                               c := new(channel)
+                               c.chanType = msg.ChanType
+                               c.theirId = msg.PeersId
+                               c.theirWindow = msg.PeersWindow
+                               c.maxPacketSize = msg.MaxPacketSize
+                               c.extraData = msg.TypeSpecificData
+                               c.myWindow = defaultWindowSize
+                               c.serverConn = s
+                               c.cond = sync.NewCond(&c.lock)
+                               c.pendingData = make([]byte, c.myWindow)
+
+                               s.lock.Lock()
+                               c.myId = s.nextChanId
+                               s.nextChanId++
+                               s.channels[c.myId] = c
+                               s.lock.Unlock()
+                               return c, nil
+
+                       case *channelRequestMsg:
+                               s.lock.Lock()
+                               c, ok := s.channels[msg.PeersId]
+                               if !ok {
+                                       s.lock.Unlock()
+                                       continue
+                               }
+                               c.handlePacket(msg)
+                               s.lock.Unlock()
 
-               case *channelCloseMsg:
-                       s.lock.Lock()
-                       c, ok := s.channels[msg.PeersId]
-                       if !ok {
-                               continue
-                       }
-                       c.handlePacket(msg)
-                       s.lock.Unlock()
+                       case *channelEOFMsg:
+                               s.lock.Lock()
+                               c, ok := s.channels[msg.PeersId]
+                               if !ok {
+                                       s.lock.Unlock()
+                                       continue
+                               }
+                               c.handlePacket(msg)
+                               s.lock.Unlock()
 
-               case *globalRequestMsg:
-                       if msg.WantReply {
-                               if err := s.writePacket([]byte{msgRequestFailure}); err != nil {
-                                       return nil, err
+                       case *channelCloseMsg:
+                               s.lock.Lock()
+                               c, ok := s.channels[msg.PeersId]
+                               if !ok {
+                                       s.lock.Unlock()
+                                       continue
                                }
-                       }
+                               c.handlePacket(msg)
+                               s.lock.Unlock()
 
-               case UnexpectedMessageError:
-                       return nil, msg
-               case *disconnectMsg:
-                       return nil, os.EOF
-               default:
-                       // Unknown message. Ignore.
+                       case *globalRequestMsg:
+                               if msg.WantReply {
+                                       if err := s.writePacket([]byte{msgRequestFailure}); err != nil {
+                                               return nil, err
+                                       }
+                               }
+
+                       case UnexpectedMessageError:
+                               return nil, msg
+                       case *disconnectMsg:
+                               return nil, os.EOF
+                       default:
+                               // Unknown message. Ignore.
+                       }
                }
        }
 
index c22ec6d..c26ae78 100644 (file)
@@ -35,19 +35,19 @@ func endsWithCSSKeyword(b []byte, kw string) bool {
 }
 
 // isCSSNmchar returns whether rune is allowed anywhere in a CSS identifier.
-func isCSSNmchar(rune int) bool {
+func isCSSNmchar(r rune) bool {
        // Based on the CSS3 nmchar production but ignores multi-rune escape
        // sequences.
        // http://www.w3.org/TR/css3-syntax/#SUBTOK-nmchar
-       return 'a' <= rune && rune <= 'z' ||
-               'A' <= rune && rune <= 'Z' ||
-               '0' <= rune && rune <= '9' ||
-               '-' == rune ||
-               '_' == rune ||
+       return 'a' <= r && r <= 'z' ||
+               'A' <= r && r <= 'Z' ||
+               '0' <= r && r <= '9' ||
+               r == '-' ||
+               r == '_' ||
                // Non-ASCII cases below.
-               0x80 <= rune && rune <= 0xd7ff ||
-               0xe000 <= rune && rune <= 0xfffd ||
-               0x10000 <= rune && rune <= 0x10ffff
+               0x80 <= r && r <= 0xd7ff ||
+               0xe000 <= r && r <= 0xfffd ||
+               0x10000 <= r && r <= 0x10ffff
 }
 
 // decodeCSS decodes CSS3 escapes given a sequence of stringchars.
@@ -81,11 +81,11 @@ func decodeCSS(s []byte) []byte {
                        for j < len(s) && j < 7 && isHex(s[j]) {
                                j++
                        }
-                       rune := hexDecode(s[1:j])
-                       if rune > unicode.MaxRune {
-                               rune, j = rune/16, j-1
+                       r := hexDecode(s[1:j])
+                       if r > unicode.MaxRune {
+                               r, j = r/16, j-1
                        }
-                       n := utf8.EncodeRune(b[len(b):cap(b)], rune)
+                       n := utf8.EncodeRune(b[len(b):cap(b)], r)
                        // The optional space at the end allows a hex
                        // sequence to be followed by a literal hex.
                        // string(decodeCSS([]byte(`\A B`))) == "\nB"
@@ -105,17 +105,17 @@ func isHex(c byte) bool {
 }
 
 // hexDecode decodes a short hex digit sequence: "10" -> 16.
-func hexDecode(s []byte) int {
-       n := 0
+func hexDecode(s []byte) rune {
+       n := rune(0)
        for _, c := range s {
                n <<= 4
                switch {
                case '0' <= c && c <= '9':
-                       n |= int(c - '0')
+                       n |= rune(c - '0')
                case 'a' <= c && c <= 'f':
-                       n |= int(c-'a') + 10
+                       n |= rune(c-'a') + 10
                case 'A' <= c && c <= 'F':
-                       n |= int(c-'A') + 10
+                       n |= rune(c-'A') + 10
                default:
                        panic(fmt.Sprintf("Bad hex digit in %q", s))
                }
@@ -251,11 +251,11 @@ func cssValueFilter(args ...interface{}) string {
                case '-':
                        // Disallow <!-- or -->.
                        // -- should not appear in valid identifiers.
-                       if i != 0 && '-' == b[i-1] {
+                       if i != 0 && b[i-1] == '-' {
                                return filterFailsafe
                        }
                default:
-                       if c < 0x80 && isCSSNmchar(int(c)) {
+                       if c < 0x80 && isCSSNmchar(rune(c)) {
                                id = append(id, c)
                        }
                }
index 5f633e8..b3b83e8 100644 (file)
@@ -35,7 +35,7 @@ func TestEndsWithCSSKeyword(t *testing.T) {
 
 func TestIsCSSNmchar(t *testing.T) {
        tests := []struct {
-               rune int
+               rune rune
                want bool
        }{
                {0, false},
@@ -114,11 +114,11 @@ 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)
-               if got := hexDecode([]byte(s)); got != i {
+               if got := int(hexDecode([]byte(s))); got != i {
                        t.Errorf("%s: want %d but got %d", s, i, got)
                }
                s = strings.ToUpper(s)
-               if got := hexDecode([]byte(s)); got != i {
+               if got := int(hexDecode([]byte(s))); got != i {
                        t.Errorf("%s: want %d but got %d", s, i, got)
                }
        }
index a4ea759..1b3b256 100644 (file)
@@ -1549,8 +1549,8 @@ func TestEnsurePipelineContains(t *testing.T) {
        }
 }
 
-func expectExecuteFailure(t *testing.T, b *bytes.Buffer) {
-       if x := recover(); x != nil {
+func expectExecuteFailure(t *testing.T, b *bytes.Buffer, err os.Error) {
+       if err != nil {
                if b.Len() != 0 {
                        t.Errorf("output on buffer: %q", b.String())
                }
@@ -1563,8 +1563,8 @@ func TestEscapeErrorsNotIgnorable(t *testing.T) {
        var b bytes.Buffer
        tmpl := template.Must(template.New("dangerous").Parse("<a"))
        Escape(tmpl)
-       defer expectExecuteFailure(t, &b)
-       tmpl.Execute(&b, nil)
+       err := tmpl.Execute(&b, nil)
+       expectExecuteFailure(t, &b, err)
 }
 
 func TestEscapeSetErrorsNotIgnorable(t *testing.T) {
@@ -1574,8 +1574,8 @@ func TestEscapeSetErrorsNotIgnorable(t *testing.T) {
        }
        EscapeSet(s, "t")
        var b bytes.Buffer
-       defer expectExecuteFailure(t, &b)
-       s.Execute(&b, "t", nil)
+       err = s.Execute(&b, "t", nil)
+       expectExecuteFailure(t, &b, err)
 }
 
 func TestRedundantFuncs(t *testing.T) {
index 91bb1b1..92d8f41 100644 (file)
@@ -139,7 +139,7 @@ var htmlNospaceNormReplacementTable = []string{
 func htmlReplacer(s string, replacementTable []string, badRunes bool) string {
        written, b := 0, new(bytes.Buffer)
        for i, r := range s {
-               if r < len(replacementTable) {
+               if int(r) < len(replacementTable) {
                        if repl := replacementTable[r]; len(repl) != 0 {
                                b.WriteString(s[written:i])
                                b.WriteString(repl)
index 98c2ac5..5646f8a 100644 (file)
@@ -85,7 +85,7 @@ func nextJSCtx(s []byte, preceding jsCtx) jsCtx {
                // Look for an IdentifierName and see if it is a keyword that
                // can precede a regular expression.
                j := n
-               for j > 0 && isJSIdentPart(int(s[j-1])) {
+               for j > 0 && isJSIdentPart(rune(s[j-1])) {
                        j--
                }
                if regexpPrecederKeywords[string(s[j:])] {
@@ -234,7 +234,7 @@ func replace(s string, replacementTable []string) string {
        for i, r := range s {
                var repl string
                switch {
-               case r < len(replacementTable) && replacementTable[r] != "":
+               case int(r) < len(replacementTable) && replacementTable[r] != "":
                        repl = replacementTable[r]
                case r == '\u2028':
                        repl = `\u2028`
@@ -329,17 +329,17 @@ var jsRegexpReplacementTable = []string{
 // It does not handle all the non-Latin letters, joiners, and combining marks,
 // but it does handle every codepoint that can occur in a numeric literal or
 // a keyword.
-func isJSIdentPart(rune int) bool {
+func isJSIdentPart(r rune) bool {
        switch {
-       case '$' == rune:
+       case r == '$':
                return true
-       case '0' <= rune && rune <= '9':
+       case '0' <= r && r <= '9':
                return true
-       case 'A' <= rune && rune <= 'Z':
+       case 'A' <= r && r <= 'Z':
                return true
-       case '_' == rune:
+       case r == '_':
                return true
-       case 'a' <= rune && rune <= 'z':
+       case 'a' <= r && r <= 'z':
                return true
        }
        return false
index 3835203..784ffff 100644 (file)
@@ -17,7 +17,7 @@ import (
 
 func readGopackHeader(buf *bufio.Reader) (name string, size int, err os.Error) {
        // See $GOROOT/include/ar.h.
-       hdr := make([]byte, 64+12+6+6+8+10+2)
+       hdr := make([]byte, 16+12+6+6+8+10+2)
        _, err = io.ReadFull(buf, hdr)
        if err != nil {
                return
@@ -25,13 +25,13 @@ func readGopackHeader(buf *bufio.Reader) (name string, size int, err os.Error) {
        if trace {
                fmt.Printf("header: %s", hdr)
        }
-       s := strings.TrimSpace(string(hdr[64+12+6+6+8:][:10]))
+       s := strings.TrimSpace(string(hdr[16+12+6+6+8:][:10]))
        size, err = strconv.Atoi(s)
        if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
                err = os.NewError("invalid archive header")
                return
        }
-       name = strings.TrimSpace(string(hdr[:64]))
+       name = strings.TrimSpace(string(hdr[:16]))
        return
 }
 
index e744a63..4e5172a 100644 (file)
@@ -71,7 +71,7 @@ func findPkg(path string) (filename, id string) {
 // object/archive file and populates its scope with the results.
 type gcParser struct {
        scanner scanner.Scanner
-       tok     int                    // current token
+       tok     rune                   // current token
        lit     string                 // literal string; only valid for Ident, Int, String tokens
        id      string                 // package id of imported package
        imports map[string]*ast.Object // package id -> package object
@@ -195,7 +195,7 @@ func (p *gcParser) errorf(format string, args ...interface{}) {
        p.error(fmt.Sprintf(format, args...))
 }
 
-func (p *gcParser) expect(tok int) string {
+func (p *gcParser) expect(tok rune) string {
        lit := p.lit
        if p.tok != tok {
                p.errorf("expected %q, got %q (%q)", scanner.TokenString(tok), scanner.TokenString(p.tok), lit)
@@ -205,9 +205,9 @@ func (p *gcParser) expect(tok int) string {
 }
 
 func (p *gcParser) expectSpecial(tok string) {
-       sep := 'x' // not white space
+       sep := rune('x') // not white space
        i := 0
-       for i < len(tok) && p.tok == int(tok[i]) && sep > ' ' {
+       for i < len(tok) && p.tok == rune(tok[i]) && sep > ' ' {
                sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
                p.next()
                i++
@@ -260,7 +260,7 @@ func (p *gcParser) parsePkgId() *ast.Object {
 func (p *gcParser) parseDotIdent() string {
        ident := ""
        if p.tok != scanner.Int {
-               sep := 'x' // not white space
+               sep := rune('x') // not white space
                for (p.tok == scanner.Ident || p.tok == scanner.Int || p.tok == '·') && sep > ' ' {
                        ident += p.lit
                        sep = p.scanner.Peek() // if sep <= ' ', there is white space before the next token
diff --git a/libgo/go/exp/types/testdata/test0.src b/libgo/go/exp/types/testdata/test0.src
new file mode 100644 (file)
index 0000000..84a1abe
--- /dev/null
@@ -0,0 +1,154 @@
+// 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.
+
+// type declarations
+
+package test0
+
+import "unsafe"
+
+const pi = 3.1415
+
+type (
+       N undeclared /* ERROR "undeclared" */
+       B bool
+       I int32
+       A [10]P
+       T struct {
+               x, y P
+       }
+       P *T
+       R (*R)
+       F func(A) I
+       Y interface {
+               f(A) I
+       }
+       S [](((P)))
+       M map[I]F
+       C chan<- I
+)
+
+
+type (
+       p1 pi /* ERROR "not a package" */ .foo
+       p2 unsafe.Pointer
+)
+
+
+type (
+       Pi pi /* ERROR "not a type" */
+
+       a /* DISABLED "illegal cycle" */ a
+       a /* ERROR "redeclared" */ int
+
+       // where the cycle error appears depends on the
+       // order in which declarations are processed
+       // (which depends on the order in which a map
+       // is iterated through)
+       b c
+       c /* DISABLED "illegal cycle" */ d
+       d e
+       e b
+
+       t *t
+
+       U V
+       V *W
+       W U
+
+       P1 *S2
+       P2 P1
+
+       S0 struct {
+       }
+       S1 struct {
+               a, b, c int
+               u, v, a /* ERROR "redeclared" */ float32
+       }
+       S2 struct {
+               U // anonymous field
+               // TODO(gri) recognize double-declaration below
+               // U /* ERROR "redeclared" */ int
+       }
+       S3 struct {
+               x S2
+       }
+       S4/* DISABLED "illegal cycle" */ struct {
+               S4
+       }
+       S5 struct {
+               S6
+       }
+       S6 /* DISABLED "illegal cycle" */ struct {
+               field S7
+       }
+       S7 struct {
+               S5
+       }
+
+       L1 []L1
+       L2 []int
+
+       A1 [10]int
+       A2 /* DISABLED "illegal cycle" */ [10]A2
+       A3 /* DISABLED "illegal cycle" */ [10]struct {
+               x A4
+       }
+       A4 [10]A3
+
+       F1 func()
+       F2 func(x, y, z float32)
+       F3 func(x, y, x /* ERROR "redeclared" */ float32)
+       F4 func() (x, y, x /* ERROR "redeclared" */ float32)
+       F5 func(x int) (x /* ERROR "redeclared" */ float32)
+       F6 func(x ...int)
+
+       I1 interface{}
+       I2 interface {
+               m1()
+       }
+       I3 interface {
+               m1()
+               m1 /* ERROR "redeclared" */ ()
+       }
+       I4 interface {
+               m1(x, y, x /* ERROR "redeclared" */ float32)
+               m2() (x, y, x /* ERROR "redeclared" */ float32)
+               m3(x int) (x /* ERROR "redeclared" */ float32)
+       }
+       I5 interface {
+               m1(I5)
+       }
+       I6 interface {
+               S0 /* ERROR "non-interface" */
+       }
+       I7 interface {
+               I1
+               I1
+       }
+       I8 /* DISABLED "illegal cycle" */ interface {
+               I8
+       }
+       I9 /* DISABLED "illegal cycle" */ interface {
+               I10
+       }
+       I10 interface {
+               I11
+       }
+       I11 interface {
+               I9
+       }
+
+       C1 chan int
+       C2 <-chan int
+       C3 chan<- C3
+       C4 chan C5
+       C5 chan C6
+       C6 chan C4
+
+       M1 map[Last]string
+       M2 map[string]M2
+
+       Last int
+)
index 80db127..f043596 100644 (file)
@@ -54,6 +54,7 @@ func init() {
 
        Bool = defType("bool")
        defType("byte") // TODO(gri) should be an alias for uint8
+       defType("rune") // TODO(gri) should be an alias for int
        defType("complex64")
        Complex128 = defType("complex128")
        defType("float32")
index 6e264d0..fb2b825 100644 (file)
@@ -40,7 +40,7 @@ func TestNotifyEvents(t *testing.T) {
        // Add a watch for testDir
        os.RemoveAll(testDir)
        if err = os.Mkdir(testDir, 0777); err != nil {
-               t.Fatalf("Failed to create test directory", err)
+               t.Fatalf("Failed to create test directory: %s", err)
        }
        defer os.RemoveAll(testDir)
        err = watcher.AddWatch(testDir, mask)
index 7b733fa..f5d6ed5 100644 (file)
@@ -102,7 +102,7 @@ func (v *Map) String() string {
                if !first {
                        fmt.Fprintf(b, ", ")
                }
-               fmt.Fprintf(b, "\"%s\": %v", key, val.String())
+               fmt.Fprintf(b, "\"%s\": %v", key, val)
                first = false
        }
        fmt.Fprintf(b, "}")
index c993e57..6713f0a 100644 (file)
        If an operand implements interface Formatter, that interface
        can be used for fine control of formatting.
 
-       If an operand implements method String() string that method
+       Next, 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). To avoid
-       recursion in cases such as
+       be formatted as required by the verb (if any).
+
+       Finally, 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:
index 38280d6..db83f85 100644 (file)
@@ -73,7 +73,7 @@ type C struct {
 
 type F int
 
-func (f F) Format(s State, c int) {
+func (f F) Format(s State, c rune) {
        Fprintf(s, "<%c=F(%d)>", c, int(f))
 }
 
@@ -356,7 +356,7 @@ var fmttests = []struct {
        {"%#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", SI{}, `fmt_test.SI{I:interface {}(nil)}`},
 
        // slices with other formats
        {"%#x", []int{1, 2, 15}, `[0x1 0x2 0xf]`},
@@ -546,7 +546,7 @@ func TestCountMallocs(t *testing.T) {
 
 type flagPrinter struct{}
 
-func (*flagPrinter) Format(f State, c int) {
+func (*flagPrinter) Format(f State, c rune) {
        s := "%"
        for i := 0; i < 128; i++ {
                if f.Flag(i) {
@@ -746,7 +746,7 @@ type PanicF struct {
 }
 
 // Value receiver.
-func (p PanicF) Format(f State, c int) {
+func (p PanicF) Format(f State, c rune) {
        panic(p.message)
 }
 
index 24b15a2..80eb986 100644 (file)
@@ -242,8 +242,8 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
        }
 
        // If we want a quoted char for %#U, move the data up to make room.
-       if f.unicode && f.uniQuote && a >= 0 && a <= unicode.MaxRune && unicode.IsPrint(int(a)) {
-               runeWidth := utf8.RuneLen(int(a))
+       if f.unicode && f.uniQuote && a >= 0 && a <= unicode.MaxRune && unicode.IsPrint(rune(a)) {
+               runeWidth := utf8.RuneLen(rune(a))
                width := 1 + 1 + runeWidth + 1 // space, quote, rune, quote
                copy(buf[i-width:], buf[i:])   // guaranteed to have enough room.
                i -= width
@@ -253,7 +253,7 @@ func (f *fmt) integer(a int64, base uint64, signedness bool, digits string) {
                j++
                buf[j] = '\''
                j++
-               utf8.EncodeRune(buf[j:], int(a))
+               utf8.EncodeRune(buf[j:], rune(a))
                j += runeWidth
                buf[j] = '\''
        }
@@ -400,7 +400,7 @@ func (f *fmt) fmt_G32(v float32) { f.plusSpace(strconv.Ftoa32(v, 'G', doPrec(f,
 func (f *fmt) fmt_fb32(v float32) { f.padString(strconv.Ftoa32(v, 'b', 0)) }
 
 // fmt_c64 formats a complex64 according to the verb.
-func (f *fmt) fmt_c64(v complex64, verb int) {
+func (f *fmt) fmt_c64(v complex64, verb rune) {
        f.buf.WriteByte('(')
        r := real(v)
        for i := 0; ; i++ {
@@ -426,7 +426,7 @@ func (f *fmt) fmt_c64(v complex64, verb int) {
 }
 
 // fmt_c128 formats a complex128 according to the verb.
-func (f *fmt) fmt_c128(v complex128, verb int) {
+func (f *fmt) fmt_c128(v complex128, verb rune) {
        f.buf.WriteByte('(')
        r := real(v)
        for i := 0; ; i++ {
index 710baee..5e0237f 100644 (file)
@@ -51,7 +51,7 @@ type State interface {
 // The implementation of Format may call Sprintf or Fprintf(f) etc.
 // to generate its output.
 type Formatter interface {
-       Format(f State, c int)
+       Format(f State, c rune)
 }
 
 // Stringer is implemented by any value that has a String method,
@@ -159,7 +159,7 @@ func (p *pp) Flag(b int) bool {
        return false
 }
 
-func (p *pp) add(c int) {
+func (p *pp) add(c rune) {
        p.buf.WriteRune(c)
 }
 
@@ -297,7 +297,7 @@ func (p *pp) unknownType(v interface{}) {
        p.buf.WriteByte('?')
 }
 
-func (p *pp) badVerb(verb int) {
+func (p *pp) badVerb(verb rune) {
        p.add('%')
        p.add('!')
        p.add(verb)
@@ -317,7 +317,7 @@ func (p *pp) badVerb(verb int) {
        p.add(')')
 }
 
-func (p *pp) fmtBool(v bool, verb int) {
+func (p *pp) fmtBool(v bool, verb rune) {
        switch verb {
        case 't', 'v':
                p.fmt.fmt_boolean(v)
@@ -328,15 +328,15 @@ func (p *pp) fmtBool(v bool, verb int) {
 
 // fmtC formats a rune for the 'c' format.
 func (p *pp) fmtC(c int64) {
-       rune := int(c) // Check for overflow.
-       if int64(rune) != c {
-               rune = utf8.RuneError
+       r := rune(c) // Check for overflow.
+       if int64(r) != c {
+               r = utf8.RuneError
        }
-       w := utf8.EncodeRune(p.runeBuf[0:utf8.UTFMax], rune)
+       w := utf8.EncodeRune(p.runeBuf[0:utf8.UTFMax], r)
        p.fmt.pad(p.runeBuf[0:w])
 }
 
-func (p *pp) fmtInt64(v int64, verb int) {
+func (p *pp) fmtInt64(v int64, verb rune) {
        switch verb {
        case 'b':
                p.fmt.integer(v, 2, signed, ldigits)
@@ -394,7 +394,7 @@ func (p *pp) fmtUnicode(v int64) {
        p.fmt.sharp = sharp
 }
 
-func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool) {
+func (p *pp) fmtUint64(v uint64, verb rune, goSyntax bool) {
        switch verb {
        case 'b':
                p.fmt.integer(int64(v), 2, unsigned, ldigits)
@@ -427,7 +427,7 @@ func (p *pp) fmtUint64(v uint64, verb int, goSyntax bool) {
        }
 }
 
-func (p *pp) fmtFloat32(v float32, verb int) {
+func (p *pp) fmtFloat32(v float32, verb rune) {
        switch verb {
        case 'b':
                p.fmt.fmt_fb32(v)
@@ -446,7 +446,7 @@ func (p *pp) fmtFloat32(v float32, verb int) {
        }
 }
 
-func (p *pp) fmtFloat64(v float64, verb int) {
+func (p *pp) fmtFloat64(v float64, verb rune) {
        switch verb {
        case 'b':
                p.fmt.fmt_fb64(v)
@@ -465,7 +465,7 @@ func (p *pp) fmtFloat64(v float64, verb int) {
        }
 }
 
-func (p *pp) fmtComplex64(v complex64, verb int) {
+func (p *pp) fmtComplex64(v complex64, verb rune) {
        switch verb {
        case 'e', 'E', 'f', 'F', 'g', 'G':
                p.fmt.fmt_c64(v, verb)
@@ -476,7 +476,7 @@ func (p *pp) fmtComplex64(v complex64, verb int) {
        }
 }
 
-func (p *pp) fmtComplex128(v complex128, verb int) {
+func (p *pp) fmtComplex128(v complex128, verb rune) {
        switch verb {
        case 'e', 'E', 'f', 'F', 'g', 'G':
                p.fmt.fmt_c128(v, verb)
@@ -487,7 +487,7 @@ func (p *pp) fmtComplex128(v complex128, verb int) {
        }
 }
 
-func (p *pp) fmtString(v string, verb int, goSyntax bool) {
+func (p *pp) fmtString(v string, verb rune, goSyntax bool) {
        switch verb {
        case 'v':
                if goSyntax {
@@ -508,7 +508,7 @@ func (p *pp) fmtString(v string, verb int, goSyntax bool) {
        }
 }
 
-func (p *pp) fmtBytes(v []byte, verb int, goSyntax bool, depth int) {
+func (p *pp) fmtBytes(v []byte, verb rune, goSyntax bool, depth int) {
        if verb == 'v' || verb == 'd' {
                if goSyntax {
                        p.buf.Write(bytesBytes)
@@ -547,7 +547,7 @@ func (p *pp) fmtBytes(v []byte, verb int, goSyntax bool, depth int) {
        }
 }
 
-func (p *pp) fmtPointer(value reflect.Value, verb int, goSyntax bool) {
+func (p *pp) fmtPointer(value reflect.Value, verb rune, goSyntax bool) {
        var u uintptr
        switch value.Kind() {
        case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
@@ -579,7 +579,7 @@ var (
        uintptrBits = reflect.TypeOf(uintptr(0)).Bits()
 )
 
-func (p *pp) catchPanic(field interface{}, verb int) {
+func (p *pp) catchPanic(field interface{}, verb rune) {
        if err := recover(); err != nil {
                // If it's a nil pointer, just say "<nil>". The likeliest causes are a
                // Stringer that fails to guard against nil or a nil pointer for a
@@ -604,7 +604,7 @@ func (p *pp) catchPanic(field interface{}, verb int) {
        }
 }
 
-func (p *pp) handleMethods(verb int, plus, goSyntax bool, depth int) (wasString, handled bool) {
+func (p *pp) handleMethods(verb rune, plus, goSyntax bool, depth int) (wasString, handled bool) {
        // Is it a Formatter?
        if formatter, ok := p.field.(Formatter); ok {
                handled = true
@@ -630,12 +630,23 @@ func (p *pp) handleMethods(verb int, plus, goSyntax bool, depth int) (wasString,
                        return
                }
        } else {
-               // Is it a Stringer?
-               if stringer, ok := p.field.(Stringer); ok {
+               // 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 os.Error:
                        wasString = false
                        handled = true
                        defer p.catchPanic(p.field, verb)
-                       p.printField(stringer.String(), verb, plus, false, depth)
+                       p.printField(v.String(), 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
                }
        }
@@ -643,7 +654,7 @@ func (p *pp) handleMethods(verb int, plus, goSyntax bool, depth int) (wasString,
        return
 }
 
-func (p *pp) printField(field interface{}, verb int, plus, goSyntax bool, depth int) (wasString bool) {
+func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth int) (wasString bool) {
        if field == nil {
                if verb == 'T' || verb == 'v' {
                        p.buf.Write(nilAngleBytes)
@@ -719,7 +730,7 @@ func (p *pp) printField(field interface{}, verb int, plus, goSyntax bool, depth
 }
 
 // printValue is like printField but starts with a reflect value, not an interface{} value.
-func (p *pp) printValue(value reflect.Value, verb int, plus, goSyntax bool, depth int) (wasString bool) {
+func (p *pp) printValue(value reflect.Value, verb rune, plus, goSyntax bool, depth int) (wasString bool) {
        if !value.IsValid() {
                if verb == 'T' || verb == 'v' {
                        p.buf.Write(nilAngleBytes)
@@ -755,7 +766,7 @@ func (p *pp) printValue(value reflect.Value, verb int, plus, goSyntax bool, dept
 
 // printReflectValue is the fallback for both printField and printValue.
 // It uses reflect to print the value.
-func (p *pp) printReflectValue(value reflect.Value, verb int, plus, goSyntax bool, depth int) (wasString bool) {
+func (p *pp) printReflectValue(value reflect.Value, verb rune, plus, goSyntax bool, depth int) (wasString bool) {
        oldValue := p.value
        p.value = value
 BigSwitch:
index 259451d..eae952c 100644 (file)
@@ -32,7 +32,7 @@ type ScanState interface {
        // If invoked during Scanln, Fscanln, or Sscanln, ReadRune() will
        // return EOF after returning the first '\n' or when reading beyond
        // the specified width.
-       ReadRune() (rune int, size int, err os.Error)
+       ReadRune() (r rune, size int, err os.Error)
        // UnreadRune causes the next call to ReadRune to return the same rune.
        UnreadRune() os.Error
        // SkipSpace skips space in the input. Newlines are treated as space 
@@ -47,7 +47,7 @@ type ScanState interface {
        // EOF.  The returned slice points to shared data that may be overwritten
        // by the next call to Token, a call to a Scan function using the ScanState
        // as input, or when the calling Scan method returns.
-       Token(skipSpace bool, f func(int) bool) (token []byte, err os.Error)
+       Token(skipSpace bool, f func(rune) bool) (token []byte, err os.Error)
        // Width returns the value of the width option and whether it has been set.
        // The unit is Unicode code points.
        Width() (wid int, ok bool)
@@ -62,7 +62,7 @@ type ScanState interface {
 // receiver, which must be a pointer to be useful.  The Scan method is called
 // for any argument to Scan, Scanf, or Scanln that implements it.
 type Scanner interface {
-       Scan(state ScanState, verb int) os.Error
+       Scan(state ScanState, verb rune) os.Error
 }
 
 // Scan scans text read from standard input, storing successive
@@ -149,8 +149,8 @@ const eof = -1
 type ss struct {
        rr       io.RuneReader // where to read input
        buf      bytes.Buffer  // token accumulator
-       peekRune int           // one-rune lookahead
-       prevRune int           // last rune returned by ReadRune
+       peekRune rune          // one-rune lookahead
+       prevRune rune          // last rune returned by ReadRune
        count    int           // runes consumed so far.
        atEOF    bool          // already read EOF
        ssave
@@ -174,12 +174,12 @@ func (s *ss) Read(buf []byte) (n int, err os.Error) {
        return 0, os.NewError("ScanState's Read should not be called. Use ReadRune")
 }
 
-func (s *ss) ReadRune() (rune int, size int, err os.Error) {
+func (s *ss) ReadRune() (r rune, size int, err os.Error) {
        if s.peekRune >= 0 {
                s.count++
-               rune = s.peekRune
-               size = utf8.RuneLen(rune)
-               s.prevRune = rune
+               r = s.peekRune
+               size = utf8.RuneLen(r)
+               s.prevRune = r
                s.peekRune = -1
                return
        }
@@ -188,10 +188,10 @@ func (s *ss) ReadRune() (rune int, size int, err os.Error) {
                return
        }
 
-       rune, size, err = s.rr.ReadRune()
+       r, size, err = s.rr.ReadRune()
        if err == nil {
                s.count++
-               s.prevRune = rune
+               s.prevRune = r
        } else if err == os.EOF {
                s.atEOF = true
        }
@@ -207,8 +207,8 @@ func (s *ss) Width() (wid int, ok bool) {
 
 // The public method returns an error; this private one panics.
 // If getRune reaches EOF, the return value is EOF (-1).
-func (s *ss) getRune() (rune int) {
-       rune, _, err := s.ReadRune()
+func (s *ss) getRune() (r rune) {
+       r, _, err := s.ReadRune()
        if err != nil {
                if err == os.EOF {
                        return eof
@@ -221,9 +221,9 @@ func (s *ss) getRune() (rune int) {
 // mustReadRune turns os.EOF into a panic(io.ErrUnexpectedEOF).
 // It is called in cases such as string scanning where an EOF is a
 // syntax error.
-func (s *ss) mustReadRune() (rune int) {
-       rune = s.getRune()
-       if rune == eof {
+func (s *ss) mustReadRune() (r rune) {
+       r = s.getRune()
+       if r == eof {
                s.error(io.ErrUnexpectedEOF)
        }
        return
@@ -248,7 +248,7 @@ func (s *ss) errorString(err string) {
        panic(scanError{os.NewError(err)})
 }
 
-func (s *ss) Token(skipSpace bool, f func(int) bool) (tok []byte, err os.Error) {
+func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err os.Error) {
        defer func() {
                if e := recover(); e != nil {
                        if se, ok := e.(scanError); ok {
@@ -267,7 +267,7 @@ func (s *ss) Token(skipSpace bool, f func(int) bool) (tok []byte, err os.Error)
 }
 
 // notSpace is the default scanning function used in Token.
-func notSpace(r int) bool {
+func notSpace(r rune) bool {
        return !unicode.IsSpace(r)
 }
 
@@ -308,13 +308,13 @@ func (r *readRune) unread(buf []byte) {
 
 // ReadRune returns the next UTF-8 encoded code point from the
 // io.Reader inside r.
-func (r *readRune) ReadRune() (rune int, size int, err os.Error) {
+func (r *readRune) ReadRune() (rr rune, size int, err os.Error) {
        r.buf[0], err = r.readByte()
        if err != nil {
                return 0, 0, err
        }
        if r.buf[0] < utf8.RuneSelf { // fast check for common ASCII case
-               rune = int(r.buf[0])
+               rr = rune(r.buf[0])
                return
        }
        var n int
@@ -328,7 +328,7 @@ func (r *readRune) ReadRune() (rune int, size int, err os.Error) {
                        return
                }
        }
-       rune, size = utf8.DecodeRune(r.buf[0:n])
+       rr, size = utf8.DecodeRune(r.buf[0:n])
        if size < n { // an error
                r.unread(r.buf[size:n])
        }
@@ -387,11 +387,11 @@ func (s *ss) free(old ssave) {
 // skipSpace skips spaces and maybe newlines.
 func (s *ss) skipSpace(stopAtNewline bool) {
        for {
-               rune := s.getRune()
-               if rune == eof {
+               r := s.getRune()
+               if r == eof {
                        return
                }
-               if rune == '\n' {
+               if r == '\n' {
                        if stopAtNewline {
                                break
                        }
@@ -401,7 +401,7 @@ func (s *ss) skipSpace(stopAtNewline bool) {
                        s.errorString("unexpected newline")
                        return
                }
-               if !unicode.IsSpace(rune) {
+               if !unicode.IsSpace(r) {
                        s.UnreadRune()
                        break
                }
@@ -411,21 +411,21 @@ func (s *ss) skipSpace(stopAtNewline bool) {
 // token returns the next space-delimited string from the input.  It
 // skips white space.  For Scanln, it stops at newlines.  For Scan,
 // newlines are treated as spaces.
-func (s *ss) token(skipSpace bool, f func(int) bool) []byte {
+func (s *ss) token(skipSpace bool, f func(rune) bool) []byte {
        if skipSpace {
                s.skipSpace(false)
        }
        // read until white space or newline
        for {
-               rune := s.getRune()
-               if rune == eof {
+               r := s.getRune()
+               if r == eof {
                        break
                }
-               if !f(rune) {
+               if !f(r) {
                        s.UnreadRune()
                        break
                }
-               s.buf.WriteRune(rune)
+               s.buf.WriteRune(r)
        }
        return s.buf.Bytes()
 }
@@ -441,17 +441,17 @@ var boolError = os.NewError("syntax error scanning boolean")
 // consume reads the next rune in the input and reports whether it is in the ok string.
 // If accept is true, it puts the character into the input token.
 func (s *ss) consume(ok string, accept bool) bool {
-       rune := s.getRune()
-       if rune == eof {
+       r := s.getRune()
+       if r == eof {
                return false
        }
-       if strings.IndexRune(ok, rune) >= 0 {
+       if strings.IndexRune(ok, r) >= 0 {
                if accept {
-                       s.buf.WriteRune(rune)
+                       s.buf.WriteRune(r)
                }
                return true
        }
-       if rune != eof && accept {
+       if r != eof && accept {
                s.UnreadRune()
        }
        return false
@@ -459,16 +459,16 @@ func (s *ss) consume(ok string, accept bool) bool {
 
 // peek reports whether the next character is in the ok string, without consuming it.
 func (s *ss) peek(ok string) bool {
-       rune := s.getRune()
-       if rune != eof {
+       r := s.getRune()
+       if r != eof {
                s.UnreadRune()
        }
-       return strings.IndexRune(ok, rune) >= 0
+       return strings.IndexRune(ok, r) >= 0
 }
 
 func (s *ss) notEOF() {
        // Guarantee there is data to be read.
-       if rune := s.getRune(); rune == eof {
+       if r := s.getRune(); r == eof {
                panic(os.EOF)
        }
        s.UnreadRune()
@@ -481,7 +481,7 @@ func (s *ss) accept(ok string) bool {
 }
 
 // okVerb verifies that the verb is present in the list, setting s.err appropriately if not.
-func (s *ss) okVerb(verb int, okVerbs, typ string) bool {
+func (s *ss) okVerb(verb rune, okVerbs, typ string) bool {
        for _, v := range okVerbs {
                if v == verb {
                        return true
@@ -492,7 +492,7 @@ func (s *ss) okVerb(verb int, okVerbs, typ string) bool {
 }
 
 // scanBool returns the value of the boolean represented by the next token.
-func (s *ss) scanBool(verb int) bool {
+func (s *ss) scanBool(verb rune) bool {
        s.skipSpace(false)
        s.notEOF()
        if !s.okVerb(verb, "tv", "boolean") {
@@ -530,7 +530,7 @@ const (
 )
 
 // getBase returns the numeric base represented by the verb and its digit string.
-func (s *ss) getBase(verb int) (base int, digits string) {
+func (s *ss) getBase(verb rune) (base int, digits string) {
        s.okVerb(verb, "bdoUxXv", "integer") // sets s.err
        base = 10
        digits = decimalDigits
@@ -564,13 +564,13 @@ func (s *ss) scanNumber(digits string, haveDigits bool) string {
 // scanRune returns the next rune value in the input.
 func (s *ss) scanRune(bitSize int) int64 {
        s.notEOF()
-       rune := int64(s.getRune())
+       r := int64(s.getRune())
        n := uint(bitSize)
-       x := (rune << (64 - n)) >> (64 - n)
-       if x != rune {
-               s.errorString("overflow on character value " + string(rune))
+       x := (r << (64 - n)) >> (64 - n)
+       if x != r {
+               s.errorString("overflow on character value " + string(r))
        }
-       return rune
+       return r
 }
 
 // scanBasePrefix reports whether the integer begins with a 0 or 0x,
@@ -593,7 +593,7 @@ func (s *ss) scanBasePrefix() (base int, digits string, found bool) {
 
 // scanInt returns the value of the integer represented by the next
 // token, checking for overflow.  Any error is stored in s.err.
-func (s *ss) scanInt(verb int, bitSize int) int64 {
+func (s *ss) scanInt(verb rune, bitSize int) int64 {
        if verb == 'c' {
                return s.scanRune(bitSize)
        }
@@ -626,7 +626,7 @@ func (s *ss) scanInt(verb int, bitSize int) int64 {
 
 // scanUint returns the value of the unsigned integer represented
 // by the next token, checking for overflow.  Any error is stored in s.err.
-func (s *ss) scanUint(verb int, bitSize int) uint64 {
+func (s *ss) scanUint(verb rune, bitSize int) uint64 {
        if verb == 'c' {
                return uint64(s.scanRune(bitSize))
        }
@@ -747,7 +747,7 @@ func (s *ss) convertFloat(str string, n int) float64 {
 // The atof argument is a type-specific reader for the underlying type.
 // If we're reading complex64, atof will parse float32s and convert them
 // to float64's to avoid reproducing this code for each complex type.
-func (s *ss) scanComplex(verb int, n int) complex128 {
+func (s *ss) scanComplex(verb rune, n int) complex128 {
        if !s.okVerb(verb, floatVerbs, "complex") {
                return 0
        }
@@ -761,7 +761,7 @@ func (s *ss) scanComplex(verb int, n int) complex128 {
 
 // convertString returns the string represented by the next input characters.
 // The format of the input is determined by the verb.
-func (s *ss) convertString(verb int) (str string) {
+func (s *ss) convertString(verb rune) (str string) {
        if !s.okVerb(verb, "svqx", "string") {
                return ""
        }
@@ -786,26 +786,26 @@ func (s *ss) quotedString() string {
        case '`':
                // Back-quoted: Anything goes until EOF or back quote.
                for {
-                       rune := s.mustReadRune()
-                       if rune == quote {
+                       r := s.mustReadRune()
+                       if r == quote {
                                break
                        }
-                       s.buf.WriteRune(rune)
+                       s.buf.WriteRune(r)
                }
                return s.buf.String()
        case '"':
                // Double-quoted: Include the quotes and let strconv.Unquote do the backslash escapes.
                s.buf.WriteRune(quote)
                for {
-                       rune := s.mustReadRune()
-                       s.buf.WriteRune(rune)
-                       if rune == '\\' {
+                       r := s.mustReadRune()
+                       s.buf.WriteRune(r)
+                       if r == '\\' {
                                // In a legal backslash escape, no matter how long, only the character
                                // immediately after the escape can itself be a backslash or quote.
                                // Thus we only need to protect the first character after the backslash.
-                               rune := s.mustReadRune()
-                               s.buf.WriteRune(rune)
-                       } else if rune == '"' {
+                               r := s.mustReadRune()
+                               s.buf.WriteRune(r)
+                       } else if r == '"' {
                                break
                        }
                }
@@ -821,7 +821,8 @@ func (s *ss) quotedString() string {
 }
 
 // hexDigit returns the value of the hexadecimal digit
-func (s *ss) hexDigit(digit int) int {
+func (s *ss) hexDigit(d rune) int {
+       digit := int(d)
        switch digit {
        case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
                return digit - '0'
@@ -871,7 +872,7 @@ const floatVerbs = "beEfFgGv"
 const hugeWid = 1 << 30
 
 // scanOne scans a single value, deriving the scanner from the type of the argument.
-func (s *ss) scanOne(verb int, field interface{}) {
+func (s *ss) scanOne(verb rune, field interface{}) {
        s.buf.Reset()
        var err os.Error
        // If the parameter has its own Scan method, use that.
@@ -997,11 +998,11 @@ func (s *ss) doScan(a []interface{}) (numProcessed int, err os.Error) {
        // Check for newline if required.
        if !s.nlIsSpace {
                for {
-                       rune := s.getRune()
-                       if rune == '\n' || rune == eof {
+                       r := s.getRune()
+                       if r == '\n' || r == eof {
                                break
                        }
-                       if !unicode.IsSpace(rune) {
+                       if !unicode.IsSpace(r) {
                                s.errorString("Scan: expected newline")
                                break
                        }
index 3f06e57..fbc28c1 100644 (file)
@@ -87,8 +87,8 @@ type FloatTest struct {
 // Xs accepts any non-empty run of the verb character
 type Xs string
 
-func (x *Xs) Scan(state ScanState, verb int) os.Error {
-       tok, err := state.Token(true, func(r int) bool { return r == verb })
+func (x *Xs) Scan(state ScanState, verb rune) os.Error {
+       tok, err := state.Token(true, func(r rune) bool { return r == verb })
        if err != nil {
                return err
        }
@@ -109,7 +109,7 @@ type IntString struct {
        s string
 }
 
-func (s *IntString) Scan(state ScanState, verb int) os.Error {
+func (s *IntString) Scan(state ScanState, verb rune) os.Error {
        if _, err := Fscan(state, &s.i); err != nil {
                return err
        }
@@ -749,8 +749,8 @@ type TwoLines string
 
 // Attempt to read two lines into the object.  Scanln should prevent this
 // because it stops at newline; Scan and Scanf should be fine.
-func (t *TwoLines) Scan(state ScanState, verb int) os.Error {
-       chars := make([]int, 0, 100)
+func (t *TwoLines) Scan(state ScanState, verb rune) os.Error {
+       chars := make([]rune, 0, 100)
        for nlCount := 0; nlCount < 2; {
                c, _, err := state.ReadRune()
                if err != nil {
@@ -812,7 +812,7 @@ type RecursiveInt struct {
        next *RecursiveInt
 }
 
-func (r *RecursiveInt) Scan(state ScanState, verb int) (err os.Error) {
+func (r *RecursiveInt) Scan(state ScanState, verb rune) (err os.Error) {
        _, err = Fscan(state, &r.i)
        if err != nil {
                return
@@ -838,8 +838,7 @@ func scanInts(r *RecursiveInt, b *bytes.Buffer) (err os.Error) {
        if err != nil {
                return
        }
-       var c int
-       c, _, err = b.ReadRune()
+       c, _, err := b.ReadRune()
        if err != nil {
                if err == os.EOF {
                        err = nil
index 22bd5ee..f8caafc 100644 (file)
@@ -752,6 +752,7 @@ type (
                Name    *Ident        // local package name (including "."); or nil
                Path    *BasicLit     // import path
                Comment *CommentGroup // line comments; or nil
+               EndPos  token.Pos     // end of spec (overrides Path.Pos if nonzero)
        }
 
        // A ValueSpec node represents a constant or variable declaration
@@ -785,7 +786,13 @@ func (s *ImportSpec) Pos() token.Pos {
 func (s *ValueSpec) Pos() token.Pos { return s.Names[0].Pos() }
 func (s *TypeSpec) Pos() token.Pos  { return s.Name.Pos() }
 
-func (s *ImportSpec) End() token.Pos { return s.Path.End() }
+func (s *ImportSpec) End() token.Pos {
+       if s.EndPos != 0 {
+               return s.EndPos
+       }
+       return s.Path.End()
+}
+
 func (s *ValueSpec) End() token.Pos {
        if n := len(s.Values); n > 0 {
                return s.Values[n-1].End()
index 62a3048..e36f99f 100644 (file)
@@ -149,7 +149,7 @@ func (p *printer) print(x reflect.Value) {
                p.print(x.Elem())
 
        case reflect.Map:
-               p.printf("%s (len = %d) {\n", x.Type().String(), x.Len())
+               p.printf("%s (len = %d) {\n", x.Type(), x.Len())
                p.indent++
                for _, key := range x.MapKeys() {
                        p.print(key)
@@ -178,7 +178,7 @@ func (p *printer) print(x reflect.Value) {
                        p.printf("%#q", s)
                        return
                }
-               p.printf("%s (len = %d) {\n", x.Type().String(), x.Len())
+               p.printf("%s (len = %d) {\n", x.Type(), x.Len())
                p.indent++
                for i, n := 0, x.Len(); i < n; i++ {
                        p.printf("%d: ", i)
@@ -189,7 +189,7 @@ func (p *printer) print(x reflect.Value) {
                p.printf("}")
 
        case reflect.Struct:
-               p.printf("%s {\n", x.Type().String())
+               p.printf("%s {\n", x.Type())
                p.indent++
                t := x.Type()
                for i, n := 0, t.NumField(); i < n; i++ {
index 68a4180..398e31c 100644 (file)
@@ -28,7 +28,7 @@ var buildPkgs = []struct {
                        GoFiles:      []string{"pkgtest.go"},
                        SFiles:       []string{"sqrt_" + runtime.GOARCH + ".s"},
                        Package:      "pkgtest",
-                       Imports:      []string{"os"},
+                       Imports:      []string{"bytes"},
                        TestImports:  []string{"fmt", "pkgtest"},
                        TestGoFiles:  sortstr([]string{"sqrt_test.go", "sqrt_" + runtime.GOARCH + "_test.go"}),
                        XTestGoFiles: []string{"xsqrt_test.go"},
index 3ee10ab..b67f999 100644 (file)
@@ -461,10 +461,10 @@ func safeName(s string) bool {
 //
 func splitQuoted(s string) (r []string, err os.Error) {
        var args []string
-       arg := make([]int, len(s))
+       arg := make([]rune, len(s))
        escaped := false
        quoted := false
-       quote := 0
+       quote := rune(0)
        i := 0
        for _, rune := range s {
                switch {
index 03ebb98..08eea1e 100644 (file)
@@ -4,9 +4,9 @@
 
 package pkgtest
 
-import "os"
+import "bytes"
 
-func Foo() os.Error {
+func Foo() *bytes.Buffer {
        return nil
 }
 
index c7fed97..9174864 100644 (file)
@@ -175,8 +175,6 @@ func setFunc(table map[string]*ast.FuncDecl, f *ast.FuncDecl) {
 }
 
 func (doc *docReader) addFunc(fun *ast.FuncDecl) {
-       name := fun.Name.Name
-
        // determine if it should be associated with a type
        if fun.Recv != nil {
                // method
@@ -205,19 +203,6 @@ func (doc *docReader) addFunc(fun *ast.FuncDecl) {
                        typ := doc.lookupTypeDoc(tname)
                        if typ != nil {
                                // named and exported result type
-
-                               // Work-around for failure of heuristic: In package os
-                               // too many functions are considered factory functions
-                               // for the Error type. Eliminate manually for now as
-                               // this appears to be the only important case in the
-                               // current library where the heuristic fails.
-                               if doc.pkgName == "os" && tname == "Error" &&
-                                       name != "NewError" && name != "NewSyscallError" {
-                                       // not a factory function for os.Error
-                                       setFunc(doc.funcs, fun) // treat as ordinary function
-                                       return
-                               }
-
                                setFunc(typ.factories, fun)
                                return
                        }
index be82b2f..e2c9441 100644 (file)
@@ -434,7 +434,9 @@ func (p *parser) parseLhsList() []ast.Expr {
        switch p.tok {
        case token.DEFINE:
                // lhs of a short variable declaration
-               p.shortVarDecl(p.makeIdentList(list))
+               // but doesn't enter scope until later:
+               // caller must call p.shortVarDecl(p.makeIdentList(list))
+               // at appropriate time.
        case token.COLON:
                // lhs of a label declaration or a communication clause of a select
                // statement (parseLhsList is not called when parsing the case clause
@@ -1398,6 +1400,9 @@ func (p *parser) parseSimpleStmt(mode int) (ast.Stmt, bool) {
                } else {
                        y = p.parseRhsList()
                }
+               if tok == token.DEFINE {
+                       p.shortVarDecl(p.makeIdentList(x))
+               }
                return &ast.AssignStmt{x, pos, tok, y}, isRange
        }
 
@@ -1722,6 +1727,9 @@ func (p *parser) parseCommClause() *ast.CommClause {
                                }
                                p.next()
                                rhs = p.parseRhs()
+                               if tok == token.DEFINE && lhs != nil {
+                                       p.shortVarDecl(p.makeIdentList(lhs))
+                               }
                        } else {
                                // rhs must be single receive operation
                                if len(lhs) > 1 {
@@ -1909,7 +1917,7 @@ func parseImportSpec(p *parser, doc *ast.CommentGroup, _ int) ast.Spec {
        p.expectSemi() // call before accessing p.linecomment
 
        // collect imports
-       spec := &ast.ImportSpec{doc, ident, path, p.lineComment}
+       spec := &ast.ImportSpec{doc, ident, path, p.lineComment, token.NoPos}
        p.imports = append(p.imports, spec)
 
        return spec
index 9705dcf..dee90fb 100644 (file)
@@ -5,6 +5,7 @@
 package parser
 
 import (
+       "go/ast"
        "go/token"
        "os"
        "testing"
@@ -134,3 +135,46 @@ func TestParse4(t *testing.T) {
                }
        }
 }
+
+func TestColonEqualsScope(t *testing.T) {
+       f, err := ParseFile(fset, "", `package p; func f() { x, y, z := x, y, z }`, 0)
+       if err != nil {
+               t.Errorf("parse: %s", err)
+       }
+
+       // RHS refers to undefined globals; LHS does not.
+       as := f.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.AssignStmt)
+       for _, v := range as.Rhs {
+               id := v.(*ast.Ident)
+               if id.Obj != nil {
+                       t.Errorf("rhs %s has Obj, should not", id.Name)
+               }
+       }
+       for _, v := range as.Lhs {
+               id := v.(*ast.Ident)
+               if id.Obj == nil {
+                       t.Errorf("lhs %s does not have Obj, should", id.Name)
+               }
+       }
+}
+
+func TestVarScope(t *testing.T) {
+       f, err := ParseFile(fset, "", `package p; func f() { var x, y, z = x, y, z }`, 0)
+       if err != nil {
+               t.Errorf("parse: %s", err)
+       }
+
+       // RHS refers to undefined globals; LHS does not.
+       as := f.Decls[0].(*ast.FuncDecl).Body.List[0].(*ast.DeclStmt).Decl.(*ast.GenDecl).Specs[0].(*ast.ValueSpec)
+       for _, v := range as.Values {
+               id := v.(*ast.Ident)
+               if id.Obj != nil {
+                       t.Errorf("rhs %s has Obj, should not", id.Name)
+               }
+       }
+       for _, id := range as.Names {
+               if id.Obj == nil {
+                       t.Errorf("lhs %s does not have Obj, should", id.Name)
+               }
+       }
+}
index 3645306..248e43d 100644 (file)
@@ -1278,6 +1278,7 @@ func (p *printer) spec(spec ast.Spec, n int, doIndent bool, multiLine *bool) {
                }
                p.expr(s.Path, multiLine)
                p.setComment(s.Comment)
+               p.print(s.EndPos)
 
        case *ast.ValueSpec:
                if n != 1 {
index a0927e4..df2a46b 100644 (file)
@@ -92,7 +92,7 @@ func (p ErrorList) String() string {
        case 1:
                return p[0].String()
        }
-       return fmt.Sprintf("%s (and %d more errors)", p[0].String(), len(p)-1)
+       return fmt.Sprintf("%s (and %d more errors)", p[0], len(p)-1)
 }
 
 // These constants control the construction of the ErrorList
index 589ec68..dfbdaa3 100644 (file)
@@ -43,7 +43,7 @@ type Scanner struct {
        mode uint         // scanning mode
 
        // scanning state
-       ch         int  // current character
+       ch         rune // current character
        offset     int  // character offset
        rdOffset   int  // reading offset (position after current character)
        lineOffset int  // current line offset
@@ -63,7 +63,7 @@ func (S *Scanner) next() {
                        S.lineOffset = S.offset
                        S.file.AddLine(S.offset)
                }
-               r, w := int(S.src[S.rdOffset]), 1
+               r, w := rune(S.src[S.rdOffset]), 1
                switch {
                case r == 0:
                        S.error(S.offset, "illegal character NUL")
@@ -232,11 +232,11 @@ func (S *Scanner) findLineEnd() bool {
        return false
 }
 
-func isLetter(ch int) bool {
+func isLetter(ch rune) bool {
        return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= 0x80 && unicode.IsLetter(ch)
 }
 
-func isDigit(ch int) bool {
+func isDigit(ch rune) bool {
        return '0' <= ch && ch <= '9' || ch >= 0x80 && unicode.IsDigit(ch)
 }
 
@@ -248,14 +248,14 @@ func (S *Scanner) scanIdentifier() token.Token {
        return token.Lookup(S.src[offs:S.offset])
 }
 
-func digitVal(ch int) int {
+func digitVal(ch rune) int {
        switch {
        case '0' <= ch && ch <= '9':
-               return ch - '0'
+               return int(ch - '0')
        case 'a' <= ch && ch <= 'f':
-               return ch - 'a' + 10
+               return int(ch - 'a' + 10)
        case 'A' <= ch && ch <= 'F':
-               return ch - 'A' + 10
+               return int(ch - 'A' + 10)
        }
        return 16 // larger than any legal digit val
 }
@@ -337,7 +337,7 @@ exit:
        return tok
 }
 
-func (S *Scanner) scanEscape(quote int) {
+func (S *Scanner) scanEscape(quote rune) {
        offs := S.offset
 
        var i, base, max uint32
@@ -462,7 +462,7 @@ func (S *Scanner) switch2(tok0, tok1 token.Token) token.Token {
        return tok0
 }
 
-func (S *Scanner) switch3(tok0, tok1 token.Token, ch2 int, tok2 token.Token) token.Token {
+func (S *Scanner) switch3(tok0, tok1 token.Token, ch2 rune, tok2 token.Token) token.Token {
        if S.ch == '=' {
                S.next()
                return tok1
@@ -474,7 +474,7 @@ func (S *Scanner) switch3(tok0, tok1 token.Token, ch2 int, tok2 token.Token) tok
        return tok0
 }
 
-func (S *Scanner) switch4(tok0, tok1 token.Token, ch2 int, tok2, tok3 token.Token) token.Token {
+func (S *Scanner) switch4(tok0, tok1 token.Token, ch2 rune, tok2, tok3 token.Token) token.Token {
        if S.ch == '=' {
                S.next()
                return tok1
index 0c2cbe6..7ed927a 100644 (file)
@@ -237,7 +237,7 @@ func TestScan(t *testing.T) {
                }
                checkPos(t, lit, pos, epos)
                if tok != e.tok {
-                       t.Errorf("bad token for %q: got %s, expected %s", lit, tok.String(), e.tok.String())
+                       t.Errorf("bad token for %q: got %s, expected %s", lit, tok, e.tok)
                }
                if e.tok.IsLiteral() && lit != e.lit {
                        t.Errorf("bad literal for %q: got %q, expected %q", lit, lit, e.lit)
@@ -286,7 +286,7 @@ func checkSemi(t *testing.T, line string, mode uint) {
                                }
                                checkPos(t, line, pos, semiPos)
                        } else {
-                               t.Errorf("bad token for %q: got %s, expected ;", line, tok.String())
+                               t.Errorf("bad token for %q: got %s, expected ;", line, tok)
                        }
                } else if tok == token.SEMICOLON {
                        t.Errorf("bad token for %q: got ;, expected no ;", line)
@@ -509,7 +509,7 @@ func TestInit(t *testing.T) {
        s.Scan()              // true
        _, tok, _ := s.Scan() // {
        if tok != token.LBRACE {
-               t.Errorf("bad token: got %s, expected %s", tok.String(), token.LBRACE)
+               t.Errorf("bad token: got %s, expected %s", tok, token.LBRACE)
        }
 
        // 2nd init
@@ -521,7 +521,7 @@ func TestInit(t *testing.T) {
        }
        _, tok, _ = s.Scan() // go
        if tok != token.GO {
-               t.Errorf("bad token: got %s, expected %s", tok.String(), token.GO)
+               t.Errorf("bad token: got %s, expected %s", tok, token.GO)
        }
 
        if s.ErrorCount != 0 {
index 2bcbf82..5306354 100644 (file)
@@ -41,7 +41,7 @@ var encodeT = []EncodeT{
 // plain test.Error call.
 func testError(t *testing.T) {
        if e := recover(); e != nil {
-               t.Error(e.(gobError).Error) // Will re-panic if not one of our errors, such as a runtime error.
+               t.Error(e.(gobError).err) // Will re-panic if not one of our errors, such as a runtime error.
        }
        return
 }
index f480087..d027d3f 100644 (file)
@@ -881,7 +881,7 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProg
                }
        }
        if op == nil {
-               errorf("decode can't handle type %s", rt.String())
+               errorf("decode can't handle type %s", rt)
        }
        return &op, indir
 }
@@ -1110,7 +1110,7 @@ func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEn
                wireStruct = wire.StructT
        }
        if wireStruct == nil {
-               errorf("type mismatch in decoder: want struct type %s; got non-struct", rt.String())
+               errorf("type mismatch in decoder: want struct type %s; got non-struct", rt)
        }
        engine = new(decEngine)
        engine.instr = make([]decInstr, len(wireStruct.Field))
index 5efcea8..1d526e3 100644 (file)
@@ -64,7 +64,7 @@ func (dec *Decoder) recvType(id typeId) {
        dec.wireType[id] = wire
 }
 
-var errBadCount = gobError{os.NewError("invalid message length")}
+var errBadCount = os.NewError("invalid message length")
 
 // recvMessage reads the next count-delimited item from the input. It is the converse
 // of Encoder.writeMessage. It returns false on EOF or other error reading the message.
index 6bb5458..c164435 100644 (file)
@@ -610,7 +610,7 @@ func (enc *Encoder) encOpFor(rt reflect.Type, inProgress map[reflect.Type]*encOp
                }
        }
        if op == nil {
-               errorf("can't happen: encode type %s", rt.String())
+               errorf("can't happen: encode type %s", rt)
        }
        return &op, indir
 }
index a774438..98c0c97 100644 (file)
@@ -606,14 +606,14 @@ func TestSliceReusesMemory(t *testing.T) {
        }
        // general slice
        {
-               x := []int("abcd")
+               x := []rune("abcd")
                enc := NewEncoder(buf)
                err := enc.Encode(x)
                if err != nil {
                        t.Errorf("ints: encode: %s", err)
                }
                // Decode into y, which is big enough.
-               y := []int("ABCDE")
+               y := []rune("ABCDE")
                addr := &y[0]
                dec := NewDecoder(buf)
                err = dec.Decode(&y)
index bfd38fc..106543d 100644 (file)
@@ -18,7 +18,7 @@ import (
 
 // A gobError wraps an os.Error and is used to distinguish errors (panics) generated in this package.
 type gobError struct {
-       os.Error
+       err os.Error
 }
 
 // errorf is like error but takes Printf-style arguments to construct an os.Error.
@@ -29,14 +29,14 @@ func errorf(format string, args ...interface{}) {
 
 // error wraps the argument error and uses it as the argument to panic.
 func error(err os.Error) {
-       panic(gobError{Error: err})
+       panic(gobError{err})
 }
 
 // catchError is meant to be used as a deferred function to turn a panic(gobError) into a
 // plain os.Error.  It overwrites the error return of the function that deferred its call.
 func catchError(err *os.Error) {
        if e := recover(); e != nil {
-               *err = e.(gobError).Error // Will re-panic if not one of our errors, such as a runtime error.
+               *err = e.(gobError).err // Will re-panic if not one of our errors, such as a runtime error.
        }
        return
 }
index 21263e2..bd83075 100644 (file)
@@ -13,7 +13,7 @@ const longestEntityWithoutSemicolon = 6
 //
 // Note that the HTML5 list is larger than the HTML4 list at
 // http://www.w3.org/TR/html4/sgml/entities.html
-var entity = map[string]int{
+var entity = map[string]rune{
        "AElig;":                           '\U000000C6',
        "AMP;":                             '\U00000026',
        "Aacute;":                          '\U000000C1',
@@ -2155,7 +2155,7 @@ var entity = map[string]int{
 }
 
 // HTML entities that are two unicode codepoints.
-var entity2 = map[string][2]int{
+var entity2 = map[string][2]rune{
        // TODO(nigeltao): Handle replacements that are wider than their names.
        // "nLt;":                     {'\u226A', '\u20D2'},
        // "nGt;":                     {'\u226B', '\u20D2'},
index e9edc47..69e0028 100644 (file)
@@ -14,7 +14,7 @@ import (
 // These replacements permit compatibility with old numeric entities that 
 // assumed Windows-1252 encoding.
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html#consume-a-character-reference
-var replacementTable = [...]int{
+var replacementTable = [...]rune{
        '\u20AC', // First entry is what 0x80 should be replaced with.
        '\u0081',
        '\u201A',
@@ -79,23 +79,23 @@ func unescapeEntity(b []byte, dst, src int, attribute bool) (dst1, src1 int) {
                        i++
                }
 
-               x := 0
+               x := rune(0)
                for i < len(s) {
                        c = s[i]
                        i++
                        if hex {
                                if '0' <= c && c <= '9' {
-                                       x = 16*x + int(c) - '0'
+                                       x = 16*x + rune(c) - '0'
                                        continue
                                } else if 'a' <= c && c <= 'f' {
-                                       x = 16*x + int(c) - 'a' + 10
+                                       x = 16*x + rune(c) - 'a' + 10
                                        continue
                                } else if 'A' <= c && c <= 'F' {
-                                       x = 16*x + int(c) - 'A' + 10
+                                       x = 16*x + rune(c) - 'A' + 10
                                        continue
                                }
                        } else if '0' <= c && c <= '9' {
-                               x = 10*x + int(c) - '0'
+                               x = 10*x + rune(c) - '0'
                                continue
                        }
                        if c != ';' {
index 4ecfd6c..5ca6035 100644 (file)
@@ -135,6 +135,8 @@ func (s *nodeStack) remove(n *Node) {
        *s = (*s)[:j]
 }
 
+// TODO(nigeltao): forTag no longer used. Should it be deleted?
+
 // forTag returns the top-most element node with the given tag.
 func (s *nodeStack) forTag(tag string) *Node {
        for i := len(*s) - 1; i >= 0; i-- {
index 530942a..54f7e2e 100644 (file)
@@ -7,6 +7,7 @@ package html
 import (
        "io"
        "os"
+       "strings"
 )
 
 // A parser implements the HTML5 parsing algorithm:
@@ -125,6 +126,7 @@ func (p *parser) addChild(n *Node) {
 // fosterParent adds a child node according to the foster parenting rules.
 // Section 11.2.5.3, "foster parenting".
 func (p *parser) fosterParent(n *Node) {
+       p.fosterParenting = false
        var table, parent *Node
        var i int
        for i = len(p.oe) - 1; i >= 0; i-- {
@@ -430,6 +432,8 @@ func beforeHeadIM(p *parser) (insertionMode, bool) {
        return inHeadIM, !implied
 }
 
+const whitespace = " \t\r\n\f"
+
 // Section 11.2.5.4.4.
 func inHeadIM(p *parser) (insertionMode, bool) {
        var (
@@ -437,13 +441,24 @@ func inHeadIM(p *parser) (insertionMode, bool) {
                implied bool
        )
        switch p.tok.Type {
-       case ErrorToken, TextToken:
+       case ErrorToken:
+               implied = 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 inHeadIM, true
+                       }
+                       p.tok.Data = s
+               }
                implied = true
        case StartTagToken:
                switch p.tok.Data {
                case "meta":
                        // TODO.
-               case "script", "title":
+               case "script", "title", "noscript", "noframes", "style":
                        p.addElement(p.tok.Data, p.tok.Attr)
                        p.setOriginalIM(inHeadIM)
                        return textIM, true
@@ -469,7 +484,7 @@ func inHeadIM(p *parser) (insertionMode, bool) {
                }
                return afterHeadIM, !implied
        }
-       return inHeadIM, !implied
+       return inHeadIM, true
 }
 
 // Section 11.2.5.4.6.
@@ -538,10 +553,13 @@ func inBodyIM(p *parser) (insertionMode, bool) {
                        }
                        p.addElement(p.tok.Data, p.tok.Attr)
                case "a":
-                       if n := p.afe.forTag("a"); n != nil {
-                               p.inBodyEndTagFormatting("a")
-                               p.oe.remove(n)
-                               p.afe.remove(n)
+                       for i := len(p.afe) - 1; i >= 0 && p.afe[i].Type != scopeMarkerNode; i-- {
+                               if n := p.afe[i]; n.Type == ElementNode && n.Data == "a" {
+                                       p.inBodyEndTagFormatting("a")
+                                       p.oe.remove(n)
+                                       p.afe.remove(n)
+                                       break
+                               }
                        }
                        p.reconstructActiveFormattingElements()
                        p.addFormattingElement(p.tok.Data, p.tok.Attr)
@@ -594,6 +612,12 @@ func inBodyIM(p *parser) (insertionMode, bool) {
                        }
                        p.popUntil(buttonScopeStopTags, "p")
                        p.addElement("li", p.tok.Attr)
+               case "optgroup", "option":
+                       if p.top().Data == "option" {
+                               p.oe.pop()
+                       }
+                       p.reconstructActiveFormattingElements()
+                       p.addElement(p.tok.Data, p.tok.Attr)
                default:
                        // TODO.
                        p.addElement(p.tok.Data, p.tok.Attr)
@@ -655,6 +679,10 @@ func (p *parser) inBodyEndTagFormatting(tag string) {
                        p.afe.remove(formattingElement)
                        return
                }
+               if !p.elementInScope(defaultScopeStopTags, tag) {
+                       // Ignore the tag.
+                       return
+               }
 
                // Steps 5-6. Find the furthest block.
                var furthestBlock *Node
@@ -732,6 +760,10 @@ func (p *parser) inBodyEndTagFormatting(tag string) {
                furthestBlock.Add(clone)
 
                // Step 14. Fix up the list of active formatting elements.
+               if oldLoc := p.afe.index(formattingElement); oldLoc != -1 && oldLoc < bookmark {
+                       // Move the bookmark with the rest of the list.
+                       bookmark--
+               }
                p.afe.remove(formattingElement)
                p.afe.insert(bookmark, clone)
 
@@ -757,6 +789,8 @@ func (p *parser) inBodyEndTagOther(tag string) {
 // Section 11.2.5.4.8.
 func textIM(p *parser) (insertionMode, bool) {
        switch p.tok.Type {
+       case ErrorToken:
+               p.oe.pop()
        case TextToken:
                p.addText(p.tok.Data)
                return textIM, true
@@ -956,7 +990,12 @@ func inCellIM(p *parser) (insertionMode, bool) {
        case EndTagToken:
                switch p.tok.Data {
                case "td", "th":
-                       // TODO.
+                       if !p.popUntil(tableScopeStopTags, p.tok.Data) {
+                               // Ignore the token.
+                               return inCellIM, true
+                       }
+                       p.clearActiveFormattingElements()
+                       return inRowIM, true
                case "body", "caption", "col", "colgroup", "html":
                        // TODO.
                case "table", "tbody", "tfoot", "thead", "tr":
index b0ddd92..b9572fa 100644 (file)
@@ -132,7 +132,7 @@ func TestParser(t *testing.T) {
                rc := make(chan io.Reader)
                go readDat(filename, rc)
                // TODO(nigeltao): Process all test cases, not just a subset.
-               for i := 0; i < 34; i++ {
+               for i := 0; i < 80; i++ {
                        // Parse the #data section.
                        b, err := ioutil.ReadAll(<-rc)
                        if err != nil {
@@ -160,14 +160,10 @@ func TestParser(t *testing.T) {
                                t.Errorf("%s test #%d %q, got vs want:\n----\n%s----\n%s----", filename, i, text, got, want)
                                continue
                        }
-                       // Check that rendering and re-parsing results in an identical tree.
-                       if filename == "tests1.dat" && i == 30 {
-                               // Test 30 in tests1.dat is such messed-up markup that a correct parse
-                               // results in a non-conforming tree (one <a> element nested inside another).
-                               // Therefore when it is rendered and re-parsed, it isn't the same.
-                               // So we skip rendering on that test.
+                       if renderTestBlacklist[text] {
                                continue
                        }
+                       // Check that rendering and re-parsing results in an identical tree.
                        pr, pw := io.Pipe()
                        go func() {
                                pw.CloseWithError(Render(pw, doc))
@@ -187,3 +183,15 @@ func TestParser(t *testing.T) {
                }
        }
 }
+
+// Some test input result in parse trees are not 'well-formed' despite
+// following the HTML5 recovery algorithms. Rendering and re-parsing such a
+// tree will not result in an exact clone of that tree. We blacklist such
+// inputs from the render test.
+var renderTestBlacklist = map[string]bool{
+       // The second <a> will be reparented to the first <table>'s parent. This
+       // results in an <a> whose parent is an <a>, which is not 'well-formed'.
+       `<a><table><td><a><table></table><a></tr><a></table><b>X</b>C<a>Y`: true,
+       // The second <a> will be reparented, similar to the case above.
+       `<a href="blah">aba<table><a href="foo">br<tr><td></td></tr>x</table>aoe`: true,
+}
index d5dc448..0522b6e 100644 (file)
@@ -19,17 +19,28 @@ type writer interface {
 
 // Render renders the parse tree n to the given writer.
 //
-// For 'well-formed' parse trees, calling Parse on the output of Render will
-// result in a clone of the original tree.
+// Rendering is done on a 'best effort' basis: calling Parse on the output of
+// Render will always result in something similar to the original tree, but it
+// is not necessarily an exact clone unless the original tree was 'well-formed'.
+// 'Well-formed' is not easily specified; the HTML5 specification is
+// complicated.
 //
-// 'Well-formed' is not formally specified, but calling Parse on arbitrary
-// input results in a 'well-formed' parse tree if Parse does not return an
-// error. Programmatically constructed trees are typically also 'well-formed',
-// but it is possible to construct a tree that, when rendered and re-parsed,
-// results in a different tree. A simple example is that a solitary text node
-// would become a tree containing <html>, <head> and <body> elements. Another
-// example is that the programmatic equivalent of "a<head>b</head>c" becomes
-// "<html><head><head/><body>abc</body></html>".
+// Calling Parse on arbitrary input typically results in a 'well-formed' parse
+// tree. However, it is possible for Parse to yield a 'badly-formed' parse tree.
+// For example, in a 'well-formed' parse tree, no <a> element is a child of
+// another <a> element: parsing "<a><a>" results in two sibling elements.
+// Similarly, in a 'well-formed' parse tree, no <a> element is a child of a
+// <table> element: parsing "<p><table><a>" results in a <p> with two sibling
+// children; the <a> is reparented to the <table>'s parent. However, calling
+// Parse on "<a><table><a>" does not return an error, but the result has an <a>
+// element with an <a> child, and is therefore not 'well-formed'.
+// 
+// Programmatically constructed trees are typically also 'well-formed', but it
+// is possible to construct a tree that looks innocuous but, when rendered and
+// re-parsed, results in a different tree. A simple example is that a solitary
+// text node would become a tree containing <html>, <head> and <body> elements.
+// Another example is that the programmatic equivalent of "a<head>b</head>c"
+// becomes "<html><head><head/><body>abc</body></html>".
 func Render(w io.Writer, n *Node) os.Error {
        if x, ok := w.(writer); ok {
                return render(x, n)
index 45ce85e..a5efdf2 100644 (file)
@@ -439,7 +439,7 @@ loop:
                }
                z.Next()
                if z.Error() != os.EOF {
-                       t.Errorf("%s: want EOF got %q", tt.desc, z.Token().String())
+                       t.Errorf("%s: want EOF got %q", tt.desc, z.Error())
                }
        }
 }
index 9ea4c9d..365a712 100644 (file)
@@ -333,18 +333,18 @@ func (h *Handler) handleInternalRedirect(rw http.ResponseWriter, req *http.Reque
        h.PathLocationHandler.ServeHTTP(rw, newReq)
 }
 
-func upperCaseAndUnderscore(rune int) int {
+func upperCaseAndUnderscore(r rune) rune {
        switch {
-       case rune >= 'a' && rune <= 'z':
-               return rune - ('a' - 'A')
-       case rune == '-':
+       case r >= 'a' && r <= 'z':
+               return r - ('a' - 'A')
+       case r == '-':
                return '_'
-       case rune == '=':
+       case r == '=':
                // Maybe not part of the CGI 'spec' but would mess up
                // the environment in any case, as Go represents the
                // environment as a slice of "key=value" strings.
                return '_'
        }
        // TODO: other transformations in spec or practice?
-       return rune
+       return r
 }
index 3f8bfdc..3a63db0 100644 (file)
@@ -69,6 +69,14 @@ func NewSingleHostReverseProxy(target *url.URL) *ReverseProxy {
        return &ReverseProxy{Director: director}
 }
 
+func copyHeader(dst, src Header) {
+       for k, vv := range src {
+               for _, v := range vv {
+                       dst.Add(k, v)
+               }
+       }
+}
+
 func (p *ReverseProxy) ServeHTTP(rw ResponseWriter, req *Request) {
        transport := p.Transport
        if transport == nil {
@@ -84,6 +92,16 @@ func (p *ReverseProxy) ServeHTTP(rw ResponseWriter, req *Request) {
        outreq.ProtoMinor = 1
        outreq.Close = false
 
+       // Remove the connection header to the backend.  We want a
+       // persistent connection, regardless of what the client sent
+       // to us.  This is modifying the same underlying map from req
+       // (shallow copied above) so we only copy it if necessary.
+       if outreq.Header.Get("Connection") != "" {
+               outreq.Header = make(Header)
+               copyHeader(outreq.Header, req.Header)
+               outreq.Header.Del("Connection")
+       }
+
        if clientIp, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {
                outreq.Header.Set("X-Forwarded-For", clientIp)
        }
@@ -95,12 +113,7 @@ func (p *ReverseProxy) ServeHTTP(rw ResponseWriter, req *Request) {
                return
        }
 
-       hdr := rw.Header()
-       for k, vv := range res.Header {
-               for _, v := range vv {
-                       hdr.Add(k, v)
-               }
-       }
+       copyHeader(rw.Header(), res.Header)
 
        rw.WriteHeader(res.StatusCode)
 
index 8078c8d..663218d 100644 (file)
@@ -24,6 +24,9 @@ func TestReverseProxy(t *testing.T) {
                if r.Header.Get("X-Forwarded-For") == "" {
                        t.Errorf("didn't get X-Forwarded-For header")
                }
+               if c := r.Header.Get("Connection"); c != "" {
+                       t.Errorf("handler got Connection header value %q", c)
+               }
                if g, e := r.Host, "some-name"; g != e {
                        t.Errorf("backend got Host header %q, want %q", g, e)
                }
@@ -43,6 +46,8 @@ func TestReverseProxy(t *testing.T) {
 
        getReq, _ := NewRequest("GET", frontend.URL, nil)
        getReq.Host = "some-name"
+       getReq.Header.Set("Connection", "close")
+       getReq.Close = true
        res, err := DefaultClient.Do(getReq)
        if err != nil {
                t.Fatalf("Get: %v", err)
index 5520634..07e2bce 100644 (file)
@@ -194,7 +194,7 @@ type ByteScanner interface {
 // and returns the rune and its size in bytes. If no character is
 // available, err will be set.
 type RuneReader interface {
-       ReadRune() (rune int, size int, err os.Error)
+       ReadRune() (r rune, size int, err os.Error)
 }
 
 // RuneScanner is the interface that adds the UnreadRune method to the
index 31b15a4..800df98 100644 (file)
@@ -588,7 +588,7 @@ func (d *decodeState) literalStore(item []byte, v reflect.Value) {
                switch v.Kind() {
                default:
                        d.saveError(&UnmarshalTypeError{"null", v.Type()})
-               case reflect.Interface, reflect.Ptr, reflect.Map:
+               case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
                        v.Set(reflect.Zero(v.Type()))
                }
 
@@ -805,15 +805,15 @@ func (d *decodeState) literalInterface() interface{} {
 
 // getu4 decodes \uXXXX from the beginning of s, returning the hex value,
 // or it returns -1.
-func getu4(s []byte) int {
+func getu4(s []byte) rune {
        if len(s) < 6 || s[0] != '\\' || s[1] != 'u' {
                return -1
        }
-       rune, err := strconv.Btoui64(string(s[2:6]), 16)
+       r, err := strconv.Btoui64(string(s[2:6]), 16)
        if err != nil {
                return -1
        }
-       return int(rune)
+       return rune(r)
 }
 
 // unquote converts a quoted JSON string literal s into an actual string t.
@@ -843,8 +843,8 @@ func unquoteBytes(s []byte) (t []byte, ok bool) {
                        r++
                        continue
                }
-               rune, size := utf8.DecodeRune(s[r:])
-               if rune == utf8.RuneError && size == 1 {
+               rr, size := utf8.DecodeRune(s[r:])
+               if rr == utf8.RuneError && size == 1 {
                        break
                }
                r += size
@@ -899,23 +899,23 @@ func unquoteBytes(s []byte) (t []byte, ok bool) {
                                w++
                        case 'u':
                                r--
-                               rune := getu4(s[r:])
-                               if rune < 0 {
+                               rr := getu4(s[r:])
+                               if rr < 0 {
                                        return
                                }
                                r += 6
-                               if utf16.IsSurrogate(rune) {
-                                       rune1 := getu4(s[r:])
-                                       if dec := utf16.DecodeRune(rune, rune1); dec != unicode.ReplacementChar {
+                               if utf16.IsSurrogate(rr) {
+                                       rr1 := getu4(s[r:])
+                                       if dec := utf16.DecodeRune(rr, rr1); dec != unicode.ReplacementChar {
                                                // A valid pair; consume.
                                                r += 6
                                                w += utf8.EncodeRune(b[w:], dec)
                                                break
                                        }
                                        // Invalid surrogate; fall back to replacement rune.
-                                       rune = unicode.ReplacementChar
+                                       rr = unicode.ReplacementChar
                                }
-                               w += utf8.EncodeRune(b[w:], rune)
+                               w += utf8.EncodeRune(b[w:], rr)
                        }
 
                // Quote, control characters are invalid.
@@ -930,9 +930,9 @@ func unquoteBytes(s []byte) (t []byte, ok bool) {
 
                // Coerce to well-formed UTF-8.
                default:
-                       rune, size := utf8.DecodeRune(s[r:])
+                       rr, size := utf8.DecodeRune(s[r:])
                        r += size
-                       w += utf8.EncodeRune(b[w:], rune)
+                       w += utf8.EncodeRune(b[w:], rr)
                }
        }
        return b[0:w], true
index 2c7cbc4..d745e8d 100644 (file)
@@ -243,7 +243,7 @@ func TestHTMLEscape(t *testing.T) {
        }
 }
 
-func noSpace(c int) int {
+func noSpace(c rune) rune {
        if isSpace(c) {
                return -1
        }
@@ -456,7 +456,7 @@ var allValueIndent = `{
        "PSlice": null,
        "PSliceP": null,
        "EmptySlice": [],
-       "NilSlice": [],
+       "NilSlice": null,
        "StringSlice": [
                "str24",
                "str25",
@@ -528,8 +528,8 @@ var pallValueIndent = `{
        },
        "EmptyMap": null,
        "NilMap": null,
-       "Slice": [],
-       "SliceP": [],
+       "Slice": null,
+       "SliceP": null,
        "PSlice": [
                {
                        "Tag": "tag20"
@@ -547,10 +547,10 @@ var pallValueIndent = `{
                        "Tag": "tag23"
                }
        ],
-       "EmptySlice": [],
-       "NilSlice": [],
-       "StringSlice": [],
-       "ByteSlice": "",
+       "EmptySlice": null,
+       "NilSlice": null,
+       "StringSlice": null,
+       "ByteSlice": null,
        "Small": {
                "Tag": ""
        },
index 46abe43..ba5c15c 100644 (file)
@@ -352,7 +352,15 @@ func (e *encodeState) reflectValueQuoted(v reflect.Value, quoted bool) {
                }
                e.WriteByte('}')
 
-       case reflect.Array, reflect.Slice:
+       case reflect.Slice:
+               if v.IsNil() {
+                       e.WriteString("null")
+                       break
+               }
+               // Slices can be marshalled as nil, but otherwise are handled
+               // as arrays.
+               fallthrough
+       case reflect.Array:
                if v.Type() == byteSliceType {
                        e.WriteByte('"')
                        s := v.Interface().([]byte)
index f85bb62..92f266a 100644 (file)
@@ -28,7 +28,7 @@ type Optionals struct {
 var optionalsExpected = `{
  "sr": "",
  "omitempty": 0,
- "slr": [],
+ "slr": null,
  "mr": {}
 }`
 
index 49c2edd..1a39b4c 100644 (file)
@@ -176,7 +176,7 @@ func (s *scanner) popParseState() {
        }
 }
 
-func isSpace(c int) bool {
+func isSpace(c rune) bool {
        return c == ' ' || c == '\t' || c == '\r' || c == '\n'
 }
 
index 4d73eac..40bf295 100644 (file)
@@ -261,13 +261,13 @@ func genValue(n int) interface{} {
 
 func genString(stddev float64) string {
        n := int(math.Abs(rand.NormFloat64()*stddev + stddev/2))
-       c := make([]int, n)
+       c := make([]rune, n)
        for i := range c {
                f := math.Abs(rand.NormFloat64()*64 + 32)
                if f > 0x10ffff {
                        f = 0x10ffff
                }
-               c[i] = int(f)
+               c[i] = rune(f)
        }
        return string(c)
 }
index f143b3f..98cb793 100644 (file)
@@ -115,7 +115,7 @@ Input:
 
 func nonSpace(b []byte) bool {
        for _, c := range b {
-               if !isSpace(int(c)) {
+               if !isSpace(rune(c)) {
                        return true
                }
        }
index e227d17..29249fb 100644 (file)
@@ -454,7 +454,7 @@ func decodeRFC2047Word(s string) (string, os.Error) {
        case "iso-8859-1":
                b := new(bytes.Buffer)
                for _, c := range dec {
-                       b.WriteRune(int(c))
+                       b.WriteRune(rune(c))
                }
                return b.String(), nil
        case "utf-8":
index 94ddea2..b540b17 100644 (file)
@@ -1709,7 +1709,7 @@ func TestCopysign(t *testing.T) {
 
 func TestCos(t *testing.T) {
        for i := 0; i < len(vf); i++ {
-               if f := Cos(vf[i]); !close(cos[i], f) {
+               if f := Cos(vf[i]); !veryclose(cos[i], f) {
                        t.Errorf("Cos(%g) = %g, want %g", vf[i], f, cos[i])
                }
        }
@@ -2192,7 +2192,7 @@ func TestSignbit(t *testing.T) {
 }
 func TestSin(t *testing.T) {
        for i := 0; i < len(vf); i++ {
-               if f := Sin(vf[i]); !close(sin[i], f) {
+               if f := Sin(vf[i]); !veryclose(sin[i], f) {
                        t.Errorf("Sin(%g) = %g, want %g", vf[i], f, sin[i])
                }
        }
@@ -2205,7 +2205,7 @@ func TestSin(t *testing.T) {
 
 func TestSincos(t *testing.T) {
        for i := 0; i < len(vf); i++ {
-               if s, c := Sincos(vf[i]); !close(sin[i], s) || !close(cos[i], c) {
+               if s, c := Sincos(vf[i]); !veryclose(sin[i], s) || !veryclose(cos[i], c) {
                        t.Errorf("Sincos(%g) = %g, %g want %g, %g", vf[i], s, c, sin[i], cos[i])
                }
        }
index 8a2edd7..9e553a2 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright 2009 The Go Authors. All rights reserved.
+// 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.
 
@@ -6,60 +6,218 @@ package math
 
 /*
        Floating-point sine and cosine.
-
-       Coefficients are #5077 from Hart & Cheney. (18.80D)
 */
 
-func sinus(x float64, quad int) float64 {
+// The original C code, the long comment, and the constants
+// below were from http://netlib.sandia.gov/cephes/cmath/sin.c,
+// available from http://www.netlib.org/cephes/cmath.tgz.
+// The go code is a simplified version of the original C.
+//
+//      sin.c
+//
+//      Circular sine
+//
+// SYNOPSIS:
+//
+// double x, y, sin();
+// y = sin( x );
+//
+// DESCRIPTION:
+//
+// Range reduction is into intervals of pi/4.  The reduction error is nearly
+// eliminated by contriving an extended precision modular arithmetic.
+//
+// Two polynomial approximating functions are employed.
+// Between 0 and pi/4 the sine is approximated by
+//      x  +  x**3 P(x**2).
+// Between pi/4 and pi/2 the cosine is represented as
+//      1  -  x**2 Q(x**2).
+//
+// ACCURACY:
+//
+//                      Relative error:
+// arithmetic   domain      # trials      peak         rms
+//    DEC       0, 10       150000       3.0e-17     7.8e-18
+//    IEEE -1.07e9,+1.07e9  130000       2.1e-16     5.4e-17
+//
+// Partial loss of accuracy begins to occur at x = 2**30 = 1.074e9.  The loss
+// is not gradual, but jumps suddenly to about 1 part in 10e7.  Results may
+// be meaningless for x > 2**49 = 5.6e14.
+//
+//      cos.c
+//
+//      Circular cosine
+//
+// SYNOPSIS:
+//
+// double x, y, cos();
+// y = cos( x );
+//
+// DESCRIPTION:
+//
+// Range reduction is into intervals of pi/4.  The reduction error is nearly
+// eliminated by contriving an extended precision modular arithmetic.
+//
+// Two polynomial approximating functions are employed.
+// Between 0 and pi/4 the cosine is approximated by
+//      1  -  x**2 Q(x**2).
+// Between pi/4 and pi/2 the sine is represented as
+//      x  +  x**3 P(x**2).
+//
+// ACCURACY:
+//
+//                      Relative error:
+// arithmetic   domain      # trials      peak         rms
+//    IEEE -1.07e9,+1.07e9  130000       2.1e-16     5.4e-17
+//    DEC        0,+1.07e9   17000       3.0e-17     7.2e-18
+//
+// Cephes Math Library Release 2.8:  June, 2000
+// Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
+//
+// The readme file at http://netlib.sandia.gov/cephes/ says:
+//    Some software in this archive may be from the book _Methods and
+// Programs for Mathematical Functions_ (Prentice-Hall or Simon & Schuster
+// International, 1989) or from the Cephes Mathematical Library, a
+// commercial product. In either event, it is copyrighted by the author.
+// What you see here may be used freely but it comes with no support or
+// guarantee.
+//
+//   The two known misprints in the book are repaired here in the
+// source listings for the gamma function and the incomplete beta
+// integral.
+//
+//   Stephen L. Moshier
+//   moshier@na-net.ornl.gov
+
+// sin coefficients
+var _sin = [...]float64{
+       1.58962301576546568060E-10, // 0x3de5d8fd1fd19ccd
+       -2.50507477628578072866E-8, // 0xbe5ae5e5a9291f5d
+       2.75573136213857245213E-6,  // 0x3ec71de3567d48a1
+       -1.98412698295895385996E-4, // 0xbf2a01a019bfdf03
+       8.33333333332211858878E-3,  // 0x3f8111111110f7d0
+       -1.66666666666666307295E-1, // 0xbfc5555555555548
+}
+// cos coefficients
+var _cos = [...]float64{
+       -1.13585365213876817300E-11, // 0xbda8fa49a0861a9b
+       2.08757008419747316778E-9,   // 0x3e21ee9d7b4e3f05
+       -2.75573141792967388112E-7,  // 0xbe927e4f7eac4bc6
+       2.48015872888517045348E-5,   // 0x3efa01a019c844f5
+       -1.38888888888730564116E-3,  // 0xbf56c16c16c14f91
+       4.16666666666665929218E-2,   // 0x3fa555555555554b
+}
+
+// Cos returns the cosine of x.
+//
+// Special conditions are:
+//     Cos(±Inf) = NaN
+//     Cos(NaN) = NaN
+func Cos(x float64) float64 {
        const (
-               P0 = .1357884097877375669092680e8
-               P1 = -.4942908100902844161158627e7
-               P2 = .4401030535375266501944918e6
-               P3 = -.1384727249982452873054457e5
-               P4 = .1459688406665768722226959e3
-               Q0 = .8644558652922534429915149e7
-               Q1 = .4081792252343299749395779e6
-               Q2 = .9463096101538208180571257e4
-               Q3 = .1326534908786136358911494e3
+               PI4A = 7.85398125648498535156E-1                             // 0x3fe921fb40000000, Pi/4 split into three parts
+               PI4B = 3.77489470793079817668E-8                             // 0x3e64442d00000000,
+               PI4C = 2.69515142907905952645E-15                            // 0x3ce8469898cc5170,
+               M4PI = 1.273239544735162542821171882678754627704620361328125 // 4/pi
        )
+       // TODO(rsc): Remove manual inlining of IsNaN, IsInf
+       // when compiler does it for us
+       // special cases
+       switch {
+       case x != x || x < -MaxFloat64 || x > MaxFloat64: // IsNaN(x) || IsInf(x, 0):
+               return NaN()
+       }
+
+       // make argument positive
+       sign := false
        if x < 0 {
                x = -x
-               quad = quad + 2
        }
-       x = x * (2 / Pi) /* underflow? */
-       var y float64
-       if x > 32764 {
-               var e float64
-               e, y = Modf(x)
-               e = e + float64(quad)
-               f, _ := Modf(0.25 * e)
-               quad = int(e - 4*f)
-       } else {
-               k := int32(x)
-               y = x - float64(k)
-               quad = (quad + int(k)) & 3
+
+       j := int64(x * M4PI) // integer part of x/(Pi/4), as integer for tests on the phase angle
+       y := float64(j)      // integer part of x/(Pi/4), as float
+
+       // map zeros to origin
+       if j&1 == 1 {
+               j += 1
+               y += 1
+       }
+       j &= 7 // octant modulo 2Pi radians (360 degrees)
+       if j > 3 {
+               j -= 4
+               sign = !sign
+       }
+       if j > 1 {
+               sign = !sign
        }
 
-       if quad&1 != 0 {
-               y = 1 - y
+       z := ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic
+       zz := z * z
+       if j == 1 || j == 2 {
+               y = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5])
+       } else {
+               y = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5])
        }
-       if quad > 1 {
+       if sign {
                y = -y
        }
-
-       yy := y * y
-       temp1 := ((((P4*yy+P3)*yy+P2)*yy+P1)*yy + P0) * y
-       temp2 := ((((yy+Q3)*yy+Q2)*yy+Q1)*yy + Q0)
-       return temp1 / temp2
+       return y
 }
 
-// Cos returns the cosine of x.
-func Cos(x float64) float64 {
+// Sin returns the sine of x.
+//
+// Special conditions are:
+//     Sin(±0) = ±0
+//     Sin(±Inf) = NaN
+//     Sin(NaN) = NaN
+func Sin(x float64) float64 {
+       const (
+               PI4A = 7.85398125648498535156E-1                             // 0x3fe921fb40000000, Pi/4 split into three parts
+               PI4B = 3.77489470793079817668E-8                             // 0x3e64442d00000000,
+               PI4C = 2.69515142907905952645E-15                            // 0x3ce8469898cc5170,
+               M4PI = 1.273239544735162542821171882678754627704620361328125 // 4/pi
+       )
+       // TODO(rsc): Remove manual inlining of IsNaN, IsInf
+       // when compiler does it for us
+       // special cases
+       switch {
+       case x == 0 || x != x: // x == 0 || IsNaN():
+               return x // return ±0 || NaN()
+       case x < -MaxFloat64 || x > MaxFloat64: // IsInf(x, 0):
+               return NaN()
+       }
+
+       // make argument positive but save the sign
+       sign := false
        if x < 0 {
                x = -x
+               sign = true
        }
-       return sinus(x, 1)
-}
 
-// Sin returns the sine of x.
-func Sin(x float64) float64 { return sinus(x, 0) }
+       j := int64(x * M4PI) // integer part of x/(Pi/4), as integer for tests on the phase angle
+       y := float64(j)      // integer part of x/(Pi/4), as float
+
+       // map zeros to origin
+       if j&1 == 1 {
+               j += 1
+               y += 1
+       }
+       j &= 7 // octant modulo 2Pi radians (360 degrees)
+       // reflect in x axis
+       if j > 3 {
+               sign = !sign
+               j -= 4
+       }
+
+       z := ((x - y*PI4A) - y*PI4B) - y*PI4C // Extended precision modular arithmetic
+       zz := z * z
+       if j == 1 || j == 2 {
+               y = 1.0 - 0.5*zz + zz*zz*((((((_cos[0]*zz)+_cos[1])*zz+_cos[2])*zz+_cos[3])*zz+_cos[4])*zz+_cos[5])
+       } else {
+               y = z + z*zz*((((((_sin[0]*zz)+_sin[1])*zz+_sin[2])*zz+_sin[3])*zz+_sin[4])*zz+_sin[5])
+       }
+       if sign {
+               y = -y
+       }
+       return y
+}
index 70a94cd..e16a06c 100644 (file)
@@ -10,16 +10,16 @@ import (
 
 // isTSpecial returns true if rune is in 'tspecials' as defined by RFC
 // 1521 and RFC 2045.
-func isTSpecial(rune int) bool {
-       return strings.IndexRune(`()<>@,;:\"/[]?=`, rune) != -1
+func isTSpecial(r rune) bool {
+       return strings.IndexRune(`()<>@,;:\"/[]?=`, r) != -1
 }
 
 // IsTokenChar returns true if rune is in 'token' as defined by RFC
 // 1521 and RFC 2045.
-func IsTokenChar(rune int) bool {
+func IsTokenChar(r rune) bool {
        // token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
        //             or tspecials>
-       return rune > 0x20 && rune < 0x7f && !isTSpecial(rune)
+       return r > 0x20 && r < 0x7f && !isTSpecial(r)
 }
 
 // IsToken returns true if s is a 'token' as as defined by RFC 1521
@@ -32,14 +32,14 @@ func IsToken(s string) bool {
 }
 
 // IsQText returns true if rune is in 'qtext' as defined by RFC 822.
-func IsQText(rune int) bool {
+func IsQText(r int) bool {
        // CHAR        =  <any ASCII character>        ; (  0-177,  0.-127.)
        // qtext       =  <any CHAR excepting <">,     ; => may be folded
        //                "\" & CR, and including
        //                linear-white-space>
-       switch rune {
+       switch r {
        case '"', '\\', '\r':
                return false
        }
-       return rune < 0x80
+       return r < 0x80
 }
index b0d3933..8ad8004 100644 (file)
@@ -199,8 +199,8 @@ func decode2231Enc(v string) string {
        return encv
 }
 
-func isNotTokenChar(rune int) bool {
-       return !IsTokenChar(rune)
+func isNotTokenChar(r rune) bool {
+       return !IsTokenChar(r)
 }
 
 // consumeToken consumes a token from the beginning of provided
@@ -228,24 +228,25 @@ func consumeValue(v string) (value, rest string) {
                return consumeToken(v)
        }
 
-       leadQuote := int(v[0])
+       leadQuote := rune(v[0])
 
        // parse a quoted-string
        rest = v[1:] // consume the leading quote
        buffer := new(bytes.Buffer)
-       var idx, rune int
+       var idx int
+       var r rune
        var nextIsLiteral bool
-       for idx, rune = range rest {
+       for idx, r = range rest {
                switch {
                case nextIsLiteral:
-                       buffer.WriteRune(rune)
+                       buffer.WriteRune(r)
                        nextIsLiteral = false
-               case rune == leadQuote:
+               case r == leadQuote:
                        return buffer.String(), rest[idx+1:]
-               case rune == '\\':
+               case r == '\\':
                        nextIsLiteral = true
-               case rune != '\r' && rune != '\n':
-                       buffer.WriteRune(rune)
+               case r != '\r' && r != '\n':
+                       buffer.WriteRune(r)
                default:
                        return "", v
                }
index d779f4a..a14c592 100644 (file)
@@ -49,7 +49,7 @@ func queryCS(net, host, service string) (res []string, err os.Error) {
 
 func queryCS1(net string, ip IP, port int) (clone, dest string, err os.Error) {
        ips := "*"
-       if !ip.IsUnspecified() {
+       if len(ip) != 0 && !ip.IsUnspecified() {
                ips = ip.String()
        }
        lines, err := queryCS(net, ips, itoa(port))
@@ -215,7 +215,16 @@ func LookupMX(name string) (mx []*MX, err os.Error) {
 
 // LookupTXT returns the DNS TXT records for the given domain name.
 func LookupTXT(name string) (txt []string, err os.Error) {
-       return nil, os.NewError("net.LookupTXT is not implemente