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 implemented on Plan 9")
+       lines, err := queryDNS(name, "txt")
+       if err != nil {
+               return
+       }
+       for _, line := range lines {
+               if i := byteIndex(line, '\t'); i >= 0 {
+                       txt = append(txt, line[i+1:])
+               }
+       }
+       return
 }
 
 // LookupAddr performs a reverse lookup for the given address, returning a list
index c0fcd26..6b7e53d 100644 (file)
@@ -52,8 +52,8 @@ func TestGmailMX(t *testing.T) {
 }
 
 func TestGmailTXT(t *testing.T) {
-       if runtime.GOOS == "windows" || runtime.GOOS == "plan9" {
-               t.Logf("LookupTXT is not implemented on Windows or Plan 9")
+       if runtime.GOOS == "windows" {
+               t.Logf("LookupTXT is not implemented on Windows")
                return
        }
        if testing.Short() || avoidMacFirewall {
index b4a6e1f..51cdac9 100644 (file)
@@ -8,6 +8,7 @@ import (
        "flag"
        "os"
        "regexp"
+       "runtime"
        "testing"
 )
 
@@ -128,6 +129,9 @@ func TestReverseAddress(t *testing.T) {
 }
 
 func TestShutdown(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               return
+       }
        l, err := Listen("tcp", "127.0.0.1:0")
        if err != nil {
                if l, err = Listen("tcp6", "[::1]:0"); err != nil {
index 5169d1e..9b9cd9e 100644 (file)
@@ -11,6 +11,13 @@ import (
 )
 
 func setKernelSpecificSockopt(s syscall.Handle, f int) {
+       // Windows will reuse recently-used addresses by default.
+       // SO_REUSEADDR should not be used here, as it allows
+       // a socket to forcibly bind to a port in use by another socket.
+       // This could lead to a non-deterministic behavior, where
+       // connection requests over the port cannot be guaranteed
+       // to be handled by the correct socket.
+
        // Allow broadcast.
        syscall.SetsockoptInt(s, syscall.SOL_SOCKET, syscall.SO_BROADCAST, 1)
 
index f4f6e9f..3319e57 100644 (file)
@@ -16,6 +16,24 @@ type TCPConn struct {
        plan9Conn
 }
 
+// CloseRead shuts down the reading side of the TCP connection.
+// Most callers should just use Close.
+func (c *TCPConn) CloseRead() os.Error {
+       if !c.ok() {
+               return os.EINVAL
+       }
+       return os.EPLAN9
+}
+
+// CloseWrite shuts down the writing side of the TCP connection.
+// Most callers should just use Close.
+func (c *TCPConn) CloseWrite() os.Error {
+       if !c.ok() {
+               return os.EINVAL
+       }
+       return os.EPLAN9
+}
+
 // DialTCP connects to the remote address raddr on the network net,
 // which must be "tcp", "tcp4", or "tcp6".  If laddr is not nil, it is used
 // as the local address for the connection.
index ece9a99..98b3927 100644 (file)
@@ -50,8 +50,22 @@ func (r *Reader) ReadLineBytes() ([]byte, os.Error) {
 
 func (r *Reader) readLineSlice() ([]byte, os.Error) {
        r.closeDot()
-       line, _, err := r.R.ReadLine()
-       return line, err
+       var line []byte
+       for {
+               l, more, err := r.R.ReadLine()
+               if err != nil {
+                       return nil, err
+               }
+               // Avoid the copy if the first call produced a full line.
+               if line == nil && !more {
+                       return l, nil
+               }
+               line = append(line, l...)
+               if !more {
+                       break
+               }
+       }
+       return line, nil
 }
 
 // ReadContinuedLine reads a possibly continued line from r,
index 23ebc3f..a087e29 100644 (file)
@@ -139,6 +139,23 @@ func TestReadMIMEHeader(t *testing.T) {
        }
 }
 
+func TestLargeReadMIMEHeader(t *testing.T) {
+       data := make([]byte, 16*1024)
+       for i := 0; i < len(data); i++ {
+               data[i] = 'x'
+       }
+       sdata := string(data)
+       r := reader("Cookie: " + sdata + "\r\n\n")
+       m, err := r.ReadMIMEHeader()
+       if err != nil {
+               t.Fatalf("ReadMIMEHeader: %v", err)
+       }
+       cookie := m.Get("Cookie")
+       if cookie != sdata {
+               t.Fatalf("ReadMIMEHeader: %v bytes, want %v bytes", len(cookie), len(sdata))
+       }
+}
+
 type readResponseTest struct {
        in       string
        inCode   int
index 0dbab58..2c2c36f 100644 (file)
@@ -6,6 +6,7 @@ package net
 
 import (
        "os"
+       "runtime"
        "testing"
        "time"
 )
@@ -41,11 +42,17 @@ func testTimeout(t *testing.T, network, addr string, readFrom bool) {
 }
 
 func TestTimeoutUDP(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               return
+       }
        testTimeout(t, "udp", "127.0.0.1:53", false)
        testTimeout(t, "udp", "127.0.0.1:53", true)
 }
 
 func TestTimeoutTCP(t *testing.T) {
+       if runtime.GOOS == "plan9" {
+               return
+       }
        // set up a listener that won't talk back
        listening := make(chan string)
        done := make(chan int)
index e8d4c08..f18d9c8 100644 (file)
@@ -119,7 +119,7 @@ type instr struct {
        index int    // used only in debugging; could be eliminated
        next  *instr // the instruction to execute after this one
        // Special fields valid only for some items.
-       char   int        // iChar
+       char   rune       // iChar
        braNum int        // iBra, iEbra
        cclass *charClass // iCharClass
        left   *instr     // iAlt, other branch
@@ -172,8 +172,8 @@ type Regexp struct {
 type charClass struct {
        negate bool // is character class negated? ([^a-z])
        // slice of int, stored pairwise: [a-z] is (a,z); x is (x,x):
-       ranges     []int
-       cmin, cmax int
+       ranges     []rune
+       cmin, cmax rune
 }
 
 func (cclass *charClass) print() {
@@ -192,7 +192,7 @@ func (cclass *charClass) print() {
        }
 }
 
-func (cclass *charClass) addRange(a, b int) {
+func (cclass *charClass) addRange(a, b rune) {
        // range is a through b inclusive
        cclass.ranges = append(cclass.ranges, a, b)
        if a < cclass.cmin {
@@ -203,7 +203,7 @@ func (cclass *charClass) addRange(a, b int) {
        }
 }
 
-func (cclass *charClass) matches(c int) bool {
+func (cclass *charClass) matches(c rune) bool {
        if c < cclass.cmin || c > cclass.cmax {
                return cclass.negate
        }
@@ -219,7 +219,7 @@ func (cclass *charClass) matches(c int) bool {
 func newCharClass() *instr {
        i := &instr{kind: iCharClass}
        i.cclass = new(charClass)
-       i.cclass.ranges = make([]int, 0, 4)
+       i.cclass.ranges = make([]rune, 0, 4)
        i.cclass.cmin = 0x10FFFF + 1 // MaxRune + 1
        i.cclass.cmax = -1
        return i
@@ -235,7 +235,7 @@ type parser struct {
        re    *Regexp
        nlpar int // number of unclosed lpars
        pos   int
-       ch    int
+       ch    rune
 }
 
 func (p *parser) error(err Error) {
@@ -244,9 +244,9 @@ func (p *parser) error(err Error) {
 
 const endOfText = -1
 
-func (p *parser) c() int { return p.ch }
+func (p *parser) c() rune { return p.ch }
 
-func (p *parser) nextc() int {
+func (p *parser) nextc() rune {
        if p.pos >= len(p.re.expr) {
                p.ch = endOfText
        } else {
@@ -264,7 +264,7 @@ func newParser(re *Regexp) *parser {
        return p
 }
 
-func special(c int) bool {
+func special(c rune) bool {
        for _, r := range `\.+*?()|[]^$` {
                if c == r {
                        return true
@@ -273,7 +273,7 @@ func special(c int) bool {
        return false
 }
 
-func ispunct(c int) bool {
+func ispunct(c rune) bool {
        for _, r := range "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~" {
                if c == r {
                        return true
@@ -285,16 +285,16 @@ func ispunct(c int) bool {
 var escapes = []byte("abfnrtv")
 var escaped = []byte("\a\b\f\n\r\t\v")
 
-func escape(c int) int {
+func escape(c rune) int {
        for i, b := range escapes {
-               if int(b) == c {
+               if rune(b) == c {
                        return i
                }
        }
        return -1
 }
 
-func (p *parser) checkBackslash() int {
+func (p *parser) checkBackslash() rune {
        c := p.c()
        if c == '\\' {
                c = p.nextc()
@@ -304,7 +304,7 @@ func (p *parser) checkBackslash() int {
                case ispunct(c):
                        // c is as delivered
                case escape(c) >= 0:
-                       c = int(escaped[escape(c)])
+                       c = rune(escaped[escape(c)])
                default:
                        p.error(ErrBadBackslash)
                }
@@ -319,7 +319,7 @@ func (p *parser) charClass() *instr {
                cc.negate = true
                p.nextc()
        }
-       left := -1
+       left := rune(-1)
        for {
                switch c := p.c(); c {
                case ']', endOfText:
@@ -751,8 +751,8 @@ func (a *matchArena) addState(s []state, inst *instr, prefixed bool, match *matc
 // input abstracts different representations of the input text. It provides
 // one-character lookahead.
 type input interface {
-       step(pos int) (rune int, width int) // advance one rune
-       canCheckPrefix() bool               // can we look ahead without losing info?
+       step(pos int) (r rune, width int) // advance one rune
+       canCheckPrefix() bool             // can we look ahead without losing info?
        hasPrefix(re *Regexp) bool
        index(re *Regexp, pos int) int
 }
@@ -766,7 +766,7 @@ func newInputString(str string) *inputString {
        return &inputString{str: str}
 }
 
-func (i *inputString) step(pos int) (int, int) {
+func (i *inputString) step(pos int) (rune, int) {
        if pos < len(i.str) {
                return utf8.DecodeRuneInString(i.str[pos:len(i.str)])
        }
@@ -794,7 +794,7 @@ func newInputBytes(str []byte) *inputBytes {
        return &inputBytes{str: str}
 }
 
-func (i *inputBytes) step(pos int) (int, int) {
+func (i *inputBytes) step(pos int) (rune, int) {
        if pos < len(i.str) {
                return utf8.DecodeRune(i.str[pos:len(i.str)])
        }
@@ -824,7 +824,7 @@ func newInputReader(r io.RuneReader) *inputReader {
        return &inputReader{r: r}
 }
 
-func (i *inputReader) step(pos int) (int, int) {
+func (i *inputReader) step(pos int) (rune, int) {
        if !i.atEOT && pos != i.pos {
                return endOfText, 0
 
@@ -886,7 +886,7 @@ func (re *Regexp) doExecute(i input, pos int) []int {
                atBOT: pos == 0,
                atEOT: nextChar == endOfText,
        }
-       for c, startPos := 0, pos; c != endOfText; {
+       for c, startPos := rune(0), pos; c != endOfText; {
                if !found && (pos == startPos || !anchored) {
                        // prime the pump if we haven't seen a match yet
                        match := arena.noMatch()
@@ -966,7 +966,7 @@ func (re *Regexp) doExecute(i input, pos int) []int {
 // of the regular expression re.  It returns the boolean true if the
 // literal string comprises the entire regular expression.
 func (re *Regexp) LiteralPrefix() (prefix string, complete bool) {
-       c := make([]int, len(re.inst)-2) // minus start and end.
+       c := make([]rune, len(re.inst)-2) // minus start and end.
        // First instruction is start; skip that.
        i := 0
        for inst := re.inst[0].next; inst.kind != iEnd; inst = inst.next {
@@ -1141,7 +1141,7 @@ func QuoteMeta(s string) string {
        // A byte loop is correct because all metacharacters are ASCII.
        j := 0
        for i := 0; i < len(s); i++ {
-               if special(int(s[i])) {
+               if special(rune(s[i])) {
                        b[j] = '\\'
                        j++
                }
index dedf9ad..9f8d1eb 100644 (file)
@@ -146,8 +146,8 @@ func (t *Template) parseError(err string, args ...interface{}) {
 
 // Is this an exported - upper case - name?
 func isExported(name string) bool {
-       rune, _ := utf8.DecodeRuneInString(name)
-       return unicode.IsUpper(rune)
+       r, _ := utf8.DecodeRuneInString(name)
+       return unicode.IsUpper(r)
 }
 
 // -- Lexical analysis
@@ -419,7 +419,7 @@ func (t *Template) newVariable(words []string) *variableElement {
                case '"', '`', '\'':
                        v, err := strconv.Unquote(word)
                        if err == nil && word[0] == '\'' {
-                               args[i] = []int(v)[0]
+                               args[i], _ = utf8.DecodeRuneInString(v)
                        } else {
                                args[i], lerr = v, err
                        }
index 4335d45..9f982e1 100644 (file)
@@ -69,7 +69,7 @@ func (file *File) Read(b []byte) (n int, err Error) {
        if n < 0 {
                n = 0
        }
-       if n == 0 && !iserror(e) {
+       if n == 0 && len(b) > 0 && !iserror(e) {
                return 0, EOF
        }
        if iserror(e) {
index 3277fc2..b8c4967 100644 (file)
@@ -163,6 +163,27 @@ func TestLstat(t *testing.T) {
        }
 }
 
+// Read with length 0 should not return EOF.
+func TestRead0(t *testing.T) {
+       path := sfdir + "/" + sfname
+       f, err := Open(path)
+       if err != nil {
+               t.Fatal("open failed:", err)
+       }
+       defer f.Close()
+
+       b := make([]byte, 0)
+       n, err := f.Read(b)
+       if n != 0 || err != nil {
+               t.Errorf("Read(0) = %d, %v, want 0, nil", n, err)
+       }
+       b = make([]byte, 100)
+       n, err = f.Read(b)
+       if n <= 0 || err != nil {
+               t.Errorf("Read(100) = %d, %v, want >0, nil", n, err)
+       }
+}
+
 func testReaddirnames(dir string, contents []string, t *testing.T) {
        file, err := Open(dir)
        defer file.Close()
index 0ccc87e..15c84a7 100644 (file)
@@ -136,7 +136,7 @@ func matchChunk(chunk, s string) (rest string, ok bool, err os.Error) {
                                        chunk = chunk[1:]
                                        break
                                }
-                               var lo, hi int
+                               var lo, hi rune
                                if lo, chunk, err = getEsc(chunk); err != nil {
                                        return
                                }
@@ -183,7 +183,7 @@ func matchChunk(chunk, s string) (rest string, ok bool, err os.Error) {
 }
 
 // getEsc gets a possibly-escaped character from chunk, for a character class.
-func getEsc(chunk string) (r int, nchunk string, err os.Error) {
+func getEsc(chunk string) (r rune, nchunk string, err os.Error) {
        if len(chunk) == 0 || chunk[0] == '-' || chunk[0] == ']' {
                err = ErrBadPattern
                return
index efb8c5c..e9d0327 100644 (file)
@@ -136,7 +136,7 @@ func matchChunk(chunk, s string) (rest string, ok bool, err os.Error) {
                                        chunk = chunk[1:]
                                        break
                                }
-                               var lo, hi int
+                               var lo, hi rune
                                if lo, chunk, err = getEsc(chunk); err != nil {
                                        return
                                }
@@ -183,7 +183,7 @@ func matchChunk(chunk, s string) (rest string, ok bool, err os.Error) {
 }
 
 // getEsc gets a possibly-escaped character from chunk, for a character class.
-func getEsc(chunk string) (r int, nchunk string, err os.Error) {
+func getEsc(chunk string) (r rune, nchunk string, err os.Error) {
        if len(chunk) == 0 || chunk[0] == '-' || chunk[0] == ']' {
                err = ErrBadPattern
                return
index 696bd56..98b6e23 100644 (file)
@@ -11,7 +11,7 @@ import (
        "io"
        "os"
        . "reflect"
-/*     "runtime" */
+       /*      "runtime" */
        "testing"
        "unsafe"
 )
@@ -434,7 +434,7 @@ func TestInterfaceGet(t *testing.T) {
        inter.E = 123.456
        v1 := ValueOf(&inter)
        v2 := v1.Elem().Field(0)
-       assert(t, v2.Type().String(), "interface { }")
+       assert(t, v2.Type().String(), "interface {}")
        i2 := v2.Interface()
        v3 := ValueOf(i2)
        assert(t, v3.Type().String(), "float64")
@@ -447,7 +447,7 @@ func TestInterfaceValue(t *testing.T) {
        inter.E = 123.456
        v1 := ValueOf(&inter)
        v2 := v1.Elem().Field(0)
-       assert(t, v2.Type().String(), "interface { }")
+       assert(t, v2.Type().String(), "interface {}")
        v3 := v2.Elem()
        assert(t, v3.Type().String(), "float64")
 
index 3b0e388..d7057a1 100644 (file)
@@ -90,15 +90,15 @@ func (m *machine) match(i input, pos int) bool {
                m.matchcap[i] = -1
        }
        runq, nextq := &m.q0, &m.q1
-       rune, rune1 := endOfText, endOfText
+       r, r1 := endOfText, endOfText
        width, width1 := 0, 0
-       rune, width = i.step(pos)
-       if rune != endOfText {
-               rune1, width1 = i.step(pos + width)
+       r, width = i.step(pos)
+       if r != endOfText {
+               r1, width1 = i.step(pos + width)
        }
        var flag syntax.EmptyOp
        if pos == 0 {
-               flag = syntax.EmptyOpContext(-1, rune)
+               flag = syntax.EmptyOpContext(-1, r)
        } else {
                flag = i.context(pos)
        }
@@ -112,15 +112,15 @@ func (m *machine) match(i input, pos int) bool {
                                // Have match; finished exploring alternatives.
                                break
                        }
-                       if len(m.re.prefix) > 0 && rune1 != m.re.prefixRune && i.canCheckPrefix() {
+                       if len(m.re.prefix) > 0 && r1 != m.re.prefixRune && i.canCheckPrefix() {
                                // Match requires literal prefix; fast search for it.
                                advance := i.index(m.re, pos)
                                if advance < 0 {
                                        break
                                }
                                pos += advance
-                               rune, width = i.step(pos)
-                               rune1, width1 = i.step(pos + width)
+                               r, width = i.step(pos)
+                               r1, width1 = i.step(pos + width)
                        }
                }
                if !m.matched {
@@ -129,8 +129,8 @@ func (m *machine) match(i input, pos int) bool {
                        }
                        m.add(runq, uint32(m.p.Start), pos, m.matchcap, flag, nil)
                }
-               flag = syntax.EmptyOpContext(rune, rune1)
-               m.step(runq, nextq, pos, pos+width, rune, flag)
+               flag = syntax.EmptyOpContext(r, r1)
+               m.step(runq, nextq, pos, pos+width, r, flag)
                if width == 0 {
                        break
                }
@@ -140,9 +140,9 @@ func (m *machine) match(i input, pos int) bool {
                        break
                }
                pos += width
-               rune, width = rune1, width1
-               if rune != endOfText {
-                       rune1, width1 = i.step(pos + width)
+               r, width = r1, width1
+               if r != endOfText {
+                       r1, width1 = i.step(pos + width)
                }
                runq, nextq = nextq, runq
        }
@@ -166,7 +166,7 @@ func (m *machine) clear(q *queue) {
 // The step processes the rune c (which may be endOfText),
 // which starts at position pos and ends at nextPos.
 // nextCond gives the setting for the empty-width flags after c.
-func (m *machine) step(runq, nextq *queue, pos, nextPos, c int, nextCond syntax.EmptyOp) {
+func (m *machine) step(runq, nextq *queue, pos, nextPos int, c rune, nextCond syntax.EmptyOp) {
        longest := m.re.longest
        for j := 0; j < len(runq.dense); j++ {
                d := &runq.dense[j]
index 2325f62..a1b7951 100644 (file)
@@ -83,7 +83,7 @@ type Regexp struct {
        prefix         string         // required prefix in unanchored matches
        prefixBytes    []byte         // prefix, as a []byte
        prefixComplete bool           // prefix is the entire regexp
-       prefixRune     int            // first rune in prefix
+       prefixRune     rune           // first rune in prefix
        cond           syntax.EmptyOp // empty-width conditions required at start of match
        numSubexp      int
        longest        bool
@@ -224,13 +224,13 @@ func (re *Regexp) NumSubexp() int {
        return re.numSubexp
 }
 
-const endOfText = -1
+const endOfText rune = -1
 
 // input abstracts different representations of the input text. It provides
 // one-character lookahead.
 type input interface {
-       step(pos int) (rune int, width int) // advance one rune
-       canCheckPrefix() bool               // can we look ahead without losing info?
+       step(pos int) (r rune, width int) // advance one rune
+       canCheckPrefix() bool             // can we look ahead without losing info?
        hasPrefix(re *Regexp) bool
        index(re *Regexp, pos int) int
        context(pos int) syntax.EmptyOp
@@ -245,11 +245,11 @@ func newInputString(str string) *inputString {
        return &inputString{str: str}
 }
 
-func (i *inputString) step(pos int) (int, int) {
+func (i *inputString) step(pos int) (rune, int) {
        if pos < len(i.str) {
                c := i.str[pos]
                if c < utf8.RuneSelf {
-                       return int(c), 1
+                       return rune(c), 1
                }
                return utf8.DecodeRuneInString(i.str[pos:])
        }
@@ -269,7 +269,7 @@ func (i *inputString) index(re *Regexp, pos int) int {
 }
 
 func (i *inputString) context(pos int) syntax.EmptyOp {
-       r1, r2 := -1, -1
+       r1, r2 := endOfText, endOfText
        if pos > 0 && pos <= len(i.str) {
                r1, _ = utf8.DecodeLastRuneInString(i.str[:pos])
        }
@@ -288,11 +288,11 @@ func newInputBytes(str []byte) *inputBytes {
        return &inputBytes{str: str}
 }
 
-func (i *inputBytes) step(pos int) (int, int) {
+func (i *inputBytes) step(pos int) (rune, int) {
        if pos < len(i.str) {
                c := i.str[pos]
                if c < utf8.RuneSelf {
-                       return int(c), 1
+                       return rune(c), 1
                }
                return utf8.DecodeRune(i.str[pos:])
        }
@@ -312,7 +312,7 @@ func (i *inputBytes) index(re *Regexp, pos int) int {
 }
 
 func (i *inputBytes) context(pos int) syntax.EmptyOp {
-       r1, r2 := -1, -1
+       r1, r2 := endOfText, endOfText
        if pos > 0 && pos <= len(i.str) {
                r1, _ = utf8.DecodeLastRune(i.str[:pos])
        }
@@ -333,7 +333,7 @@ func newInputReader(r io.RuneReader) *inputReader {
        return &inputReader{r: r}
 }
 
-func (i *inputReader) step(pos int) (int, int) {
+func (i *inputReader) step(pos int) (rune, int) {
        if !i.atEOT && pos != i.pos {
                return endOfText, 0
 
index c415d39..c90de3f 100644 (file)
@@ -91,8 +91,8 @@ func (c *compiler) init() {
        c.inst(InstFail)
 }
 
-var anyRuneNotNL = []int{0, '\n' - 1, '\n' + 1, unicode.MaxRune}
-var anyRune = []int{0, unicode.MaxRune}
+var anyRuneNotNL = []rune{0, '\n' - 1, '\n' + 1, unicode.MaxRune}
+var anyRune = []rune{0, unicode.MaxRune}
 
 func (c *compiler) compile(re *Regexp) frag {
        switch re.Op {
@@ -262,12 +262,12 @@ func (c *compiler) empty(op EmptyOp) frag {
        return f
 }
 
-func (c *compiler) rune(rune []int, flags Flags) frag {
+func (c *compiler) rune(r []rune, flags Flags) frag {
        f := c.inst(InstRune)
        i := &c.p.Inst[f.i]
-       i.Rune = rune
+       i.Rune = r
        flags &= FoldCase // only relevant flag is FoldCase
-       if len(rune) != 1 || unicode.SimpleFold(rune[0]) == rune[0] {
+       if len(r) != 1 || unicode.SimpleFold(r[0]) == r[0] {
                // and sometimes not even that
                flags &^= FoldCase
        }
@@ -276,11 +276,11 @@ func (c *compiler) rune(rune []int, flags Flags) frag {
 
        // Special cases for exec machine.
        switch {
-       case flags&FoldCase == 0 && (len(rune) == 1 || len(rune) == 2 && rune[0] == rune[1]):
+       case flags&FoldCase == 0 && (len(r) == 1 || len(r) == 2 && r[0] == r[1]):
                i.Op = InstRune1
-       case len(rune) == 2 && rune[0] == 0 && rune[1] == unicode.MaxRune:
+       case len(r) == 2 && r[0] == 0 && r[1] == unicode.MaxRune:
                i.Op = InstRuneAny
-       case len(rune) == 4 && rune[0] == 0 && rune[1] == '\n'-1 && rune[2] == '\n'+1 && rune[3] == unicode.MaxRune:
+       case len(r) == 4 && r[0] == 0 && r[1] == '\n'-1 && r[2] == '\n'+1 && r[3] == unicode.MaxRune:
                i.Op = InstRuneAnyNotNL
        }
 
index 7013459..bb19c5a 100644 (file)
@@ -82,7 +82,7 @@ type parser struct {
        free        *Regexp
        numCap      int // number of capturing groups seen
        wholeRegexp string
-       tmpClass    []int // temporary char class work space
+       tmpClass    []rune // temporary char class work space
 }
 
 func (p *parser) newRegexp(op Op) *Regexp {
@@ -149,7 +149,7 @@ func (p *parser) push(re *Regexp) *Regexp {
 // If r >= 0 and there's a node left over, maybeConcat uses it
 // to push r with the given flags.
 // maybeConcat reports whether r was pushed.
-func (p *parser) maybeConcat(r int, flags Flags) bool {
+func (p *parser) maybeConcat(r rune, flags Flags) bool {
        n := len(p.stack)
        if n < 2 {
                return false
@@ -178,7 +178,7 @@ func (p *parser) maybeConcat(r int, flags Flags) bool {
 }
 
 // newLiteral returns a new OpLiteral Regexp with the given flags
-func (p *parser) newLiteral(r int, flags Flags) *Regexp {
+func (p *parser) newLiteral(r rune, flags Flags) *Regexp {
        re := p.newRegexp(OpLiteral)
        re.Flags = flags
        if flags&FoldCase != 0 {
@@ -190,7 +190,7 @@ func (p *parser) newLiteral(r int, flags Flags) *Regexp {
 }
 
 // minFoldRune returns the minimum rune fold-equivalent to r.
-func minFoldRune(r int) int {
+func minFoldRune(r rune) rune {
        if r < MinFold || r > MaxFold {
                return r
        }
@@ -206,7 +206,7 @@ func minFoldRune(r int) int {
 
 // literal pushes a literal regexp for the rune r on the stack
 // and returns that regexp.
-func (p *parser) literal(r int) {
+func (p *parser) literal(r rune) {
        p.push(p.newLiteral(r, p.flags))
 }
 
@@ -369,7 +369,7 @@ func (p *parser) factor(sub []*Regexp, flags Flags) []*Regexp {
        }
 
        // Round 1: Factor out common literal prefixes.
-       var str []int
+       var str []rune
        var strflags Flags
        start := 0
        out := sub[:0]
@@ -380,7 +380,7 @@ func (p *parser) factor(sub []*Regexp, flags Flags) []*Regexp {
                //
                // Invariant: sub[start:i] consists of regexps that all begin
                // with str as modified by strflags.
-               var istr []int
+               var istr []rune
                var iflags Flags
                if i < len(sub) {
                        istr, iflags = p.leadingString(sub[i])
@@ -543,7 +543,7 @@ func (p *parser) factor(sub []*Regexp, flags Flags) []*Regexp {
 
 // leadingString returns the leading literal string that re begins with.
 // The string refers to storage in re or its children.
-func (p *parser) leadingString(re *Regexp) ([]int, Flags) {
+func (p *parser) leadingString(re *Regexp) ([]rune, Flags) {
        if re.Op == OpConcat && len(re.Sub) > 0 {
                re = re.Sub[0]
        }
@@ -639,7 +639,7 @@ func literalRegexp(s string, flags Flags) *Regexp {
        for _, c := range s {
                if len(re.Rune) >= cap(re.Rune) {
                        // string is too long to fit in Rune0.  let Go handle it
-                       re.Rune = []int(s)
+                       re.Rune = []rune(s)
                        break
                }
                re.Rune = append(re.Rune, c)
@@ -662,7 +662,7 @@ func Parse(s string, flags Flags) (*Regexp, os.Error) {
        var (
                p          parser
                err        os.Error
-               c          int
+               c          rune
                op         Op
                lastRepeat string
                min, max   int
@@ -935,7 +935,7 @@ func (p *parser) parsePerlFlags(s string) (rest string, err os.Error) {
        }
 
        // Non-capturing group.  Might also twiddle Perl flags.
-       var c int
+       var c rune
        t = t[2:] // skip (?
        flags := p.flags
        sign := +1
@@ -1049,7 +1049,7 @@ func isCharClass(re *Regexp) bool {
 }
 
 // does re match r?
-func matchRune(re *Regexp, r int) bool {
+func matchRune(re *Regexp, r rune) bool {
        switch re.Op {
        case OpLiteral:
                return len(re.Rune) == 1 && re.Rune[0] == r
@@ -1186,7 +1186,7 @@ func (p *parser) parseRightParen() os.Error {
 
 // parseEscape parses an escape sequence at the beginning of s
 // and returns the rune.
-func (p *parser) parseEscape(s string) (r int, rest string, err os.Error) {
+func (p *parser) parseEscape(s string) (r rune, rest string, err os.Error) {
        t := s[1:]
        if t == "" {
                return 0, "", &Error{ErrTrailingBackslash, ""}
@@ -1221,7 +1221,7 @@ Switch:
                        if t == "" || t[0] < '0' || t[0] > '7' {
                                break
                        }
-                       r = r*8 + int(t[0]) - '0'
+                       r = r*8 + rune(t[0]) - '0'
                        t = t[1:]
                }
                return r, t, nil
@@ -1302,7 +1302,7 @@ Switch:
 
 // parseClassChar parses a character class character at the beginning of s
 // and returns it.
-func (p *parser) parseClassChar(s, wholeClass string) (r int, rest string, err os.Error) {
+func (p *parser) parseClassChar(s, wholeClass string) (r rune, rest string, err os.Error) {
        if s == "" {
                return 0, "", &Error{Code: ErrMissingBracket, Expr: wholeClass}
        }
@@ -1318,13 +1318,13 @@ func (p *parser) parseClassChar(s, wholeClass string) (r int, rest string, err o
 
 type charGroup struct {
        sign  int
-       class []int
+       class []rune
 }
 
 // parsePerlClassEscape parses a leading Perl character class escape like \d
 // from the beginning of s.  If one is present, it appends the characters to r
 // and returns the new slice r and the remainder of the string.
-func (p *parser) parsePerlClassEscape(s string, r []int) (out []int, rest string) {
+func (p *parser) parsePerlClassEscape(s string, r []rune) (out []rune, rest string) {
        if p.flags&PerlX == 0 || len(s) < 2 || s[0] != '\\' {
                return
        }
@@ -1338,7 +1338,7 @@ func (p *parser) parsePerlClassEscape(s string, r []int) (out []int, rest string
 // parseNamedClass parses a leading POSIX named character class like [:alnum:]
 // from the beginning of s.  If one is present, it appends the characters to r
 // and returns the new slice r and the remainder of the string.
-func (p *parser) parseNamedClass(s string, r []int) (out []int, rest string, err os.Error) {
+func (p *parser) parseNamedClass(s string, r []rune) (out []rune, rest string, err os.Error) {
        if len(s) < 2 || s[0] != '[' || s[1] != ':' {
                return
        }
@@ -1356,7 +1356,7 @@ func (p *parser) parseNamedClass(s string, r []int) (out []int, rest string, err
        return p.appendGroup(r, g), s, nil
 }
 
-func (p *parser) appendGroup(r []int, g charGroup) []int {
+func (p *parser) appendGroup(r []rune, g charGroup) []rune {
        if p.flags&FoldCase == 0 {
                if g.sign < 0 {
                        r = appendNegatedClass(r, g.class)
@@ -1401,7 +1401,7 @@ func unicodeTable(name string) (*unicode.RangeTable, *unicode.RangeTable) {
 // parseUnicodeClass parses a leading Unicode character class like \p{Han}
 // from the beginning of s.  If one is present, it appends the characters to r
 // and returns the new slice r and the remainder of the string.
-func (p *parser) parseUnicodeClass(s string, r []int) (out []int, rest string, err os.Error) {
+func (p *parser) parseUnicodeClass(s string, r []rune) (out []rune, rest string, err os.Error) {
        if p.flags&UnicodeGroups == 0 || len(s) < 2 || s[0] != '\\' || s[1] != 'p' && s[1] != 'P' {
                return
        }
@@ -1533,7 +1533,7 @@ func (p *parser) parseClass(s string) (rest string, err os.Error) {
 
                // Single character or simple range.
                rng := t
-               var lo, hi int
+               var lo, hi rune
                if lo, t, err = p.parseClassChar(t, s); err != nil {
                        return "", err
                }
@@ -1570,7 +1570,7 @@ func (p *parser) parseClass(s string) (rest string, err os.Error) {
 
 // cleanClass sorts the ranges (pairs of elements of r),
 // merges them, and eliminates duplicates.
-func cleanClass(rp *[]int) []int {
+func cleanClass(rp *[]rune) []rune {
 
        // Sort by lo increasing, hi decreasing to break ties.
        sort.Sort(ranges{rp})
@@ -1601,15 +1601,15 @@ func cleanClass(rp *[]int) []int {
 }
 
 // appendLiteral returns the result of appending the literal x to the class r.
-func appendLiteral(r []int, x int, flags Flags) []int {
+func appendLiteral(r []rune, x rune, flags Flags) []rune {
        if flags&FoldCase != 0 {
                return appendFoldedRange(r, x, x)
        }
        return AppendRange(r, x, x)
 }
 
-// AppendRange returns the result of appending the range lo-hi to the class r.
-func AppendRange(r []int, lo, hi int) []int {
+// appendRange returns the result of appending the range lo-hi to the class r.
+func AppendRange(r []rune, lo, hi rune) []rune {
        // Expand last range or next to last range if it overlaps or abuts.
        // Checking two ranges helps when appending case-folded
        // alphabets, so that one range can be expanding A-Z and the
@@ -1642,7 +1642,7 @@ const (
 
 // appendFoldedRange returns the result of appending the range lo-hi
 // and its case folding-equivalent runes to the class r.
-func appendFoldedRange(r []int, lo, hi int) []int {
+func appendFoldedRange(r []rune, lo, hi rune) []rune {
        // Optimizations.
        if lo <= MinFold && hi >= MaxFold {
                // Range is full: folding can't add more.
@@ -1677,7 +1677,7 @@ func appendFoldedRange(r []int, lo, hi int) []int {
 
 // appendClass returns the result of appending the class x to the class r.
 // It assume x is clean.
-func appendClass(r []int, x []int) []int {
+func appendClass(r []rune, x []rune) []rune {
        for i := 0; i < len(x); i += 2 {
                r = AppendRange(r, x[i], x[i+1])
        }
@@ -1685,7 +1685,7 @@ func appendClass(r []int, x []int) []int {
 }
 
 // appendFolded returns the result of appending the case folding of the class x to the class r.
-func appendFoldedClass(r []int, x []int) []int {
+func appendFoldedClass(r []rune, x []rune) []rune {
        for i := 0; i < len(x); i += 2 {
                r = appendFoldedRange(r, x[i], x[i+1])
        }
@@ -1694,8 +1694,8 @@ func appendFoldedClass(r []int, x []int) []int {
 
 // appendNegatedClass returns the result of appending the negation of the class x to the class r.
 // It assumes x is clean.
-func appendNegatedClass(r []int, x []int) []int {
-       nextLo := 0
+func appendNegatedClass(r []rune, x []rune) []rune {
+       nextLo := rune('\u0000')
        for i := 0; i < len(x); i += 2 {
                lo, hi := x[i], x[i+1]
                if nextLo <= lo-1 {
@@ -1710,9 +1710,9 @@ func appendNegatedClass(r []int, x []int) []int {
 }
 
 // appendTable returns the result of appending x to the class r.
-func appendTable(r []int, x *unicode.RangeTable) []int {
+func appendTable(r []rune, x *unicode.RangeTable) []rune {
        for _, xr := range x.R16 {
-               lo, hi, stride := int(xr.Lo), int(xr.Hi), int(xr.Stride)
+               lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
                if stride == 1 {
                        r = AppendRange(r, lo, hi)
                        continue
@@ -1722,7 +1722,7 @@ func appendTable(r []int, x *unicode.RangeTable) []int {
                }
        }
        for _, xr := range x.R32 {
-               lo, hi, stride := int(xr.Lo), int(xr.Hi), int(xr.Stride)
+               lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
                if stride == 1 {
                        r = AppendRange(r, lo, hi)
                        continue
@@ -1735,10 +1735,10 @@ func appendTable(r []int, x *unicode.RangeTable) []int {
 }
 
 // appendNegatedTable returns the result of appending the negation of x to the class r.
-func appendNegatedTable(r []int, x *unicode.RangeTable) []int {
-       nextLo := 0 // lo end of next class to add
+func appendNegatedTable(r []rune, x *unicode.RangeTable) []rune {
+       nextLo := rune('\u0000') // lo end of next class to add
        for _, xr := range x.R16 {
-               lo, hi, stride := int(xr.Lo), int(xr.Hi), int(xr.Stride)
+               lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
                if stride == 1 {
                        if nextLo <= lo-1 {
                                r = AppendRange(r, nextLo, lo-1)
@@ -1754,7 +1754,7 @@ func appendNegatedTable(r []int, x *unicode.RangeTable) []int {
                }
        }
        for _, xr := range x.R32 {
-               lo, hi, stride := int(xr.Lo), int(xr.Hi), int(xr.Stride)
+               lo, hi, stride := rune(xr.Lo), rune(xr.Hi), rune(xr.Stride)
                if stride == 1 {
                        if nextLo <= lo-1 {
                                r = AppendRange(r, nextLo, lo-1)
@@ -1777,9 +1777,9 @@ func appendNegatedTable(r []int, x *unicode.RangeTable) []int {
 
 // negateClass overwrites r and returns r's negation.
 // It assumes the class r is already clean.
-func negateClass(r []int) []int {
-       nextLo := 0 // lo end of next class to add
-       w := 0      // write index
+func negateClass(r []rune) []rune {
+       nextLo := rune('\u0000') // lo end of next class to add
+       w := 0                   // write index
        for i := 0; i < len(r); i += 2 {
                lo, hi := r[i], r[i+1]
                if nextLo <= lo-1 {
@@ -1801,9 +1801,9 @@ func negateClass(r []int) []int {
 // ranges implements sort.Interface on a []rune.
 // The choice of receiver type definition is strange
 // but avoids an allocation since we already have
-// a *[]int.
+// a *[]rune.
 type ranges struct {
-       p *[]int
+       p *[]rune
 }
 
 func (ra ranges) Less(i, j int) bool {
@@ -1835,7 +1835,7 @@ func checkUTF8(s string) os.Error {
        return nil
 }
 
-func nextRune(s string) (c int, t string, err os.Error) {
+func nextRune(s string) (c rune, t string, err os.Error) {
        c, size := utf8.DecodeRuneInString(s)
        if c == utf8.RuneError && size == 1 {
                return 0, "", &Error{Code: ErrInvalidUTF8, Expr: s}
@@ -1843,11 +1843,11 @@ func nextRune(s string) (c int, t string, err os.Error) {
        return c, s[size:], nil
 }
 
-func isalnum(c int) bool {
+func isalnum(c rune) bool {
        return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'
 }
 
-func unhex(c int) int {
+func unhex(c rune) rune {
        if '0' <= c && c <= '9' {
                return c - '0'
        }
index 5d9085b..88f65ec 100644 (file)
@@ -5,9 +5,9 @@
 package syntax_test
 
 import (
-       . "regexp/syntax"
        "bytes"
        "fmt"
+       . "regexp/syntax"
        "testing"
        "unicode"
 )
@@ -372,10 +372,10 @@ func dumpRegexp(b *bytes.Buffer, re *Regexp) {
        b.WriteByte('}')
 }
 
-func mkCharClass(f func(int) bool) string {
+func mkCharClass(f func(rune) bool) string {
        re := &Regexp{Op: OpCharClass}
-       lo := -1
-       for i := 0; i <= unicode.MaxRune; i++ {
+       lo := rune(-1)
+       for i := rune(0); i <= unicode.MaxRune; i++ {
                if f(i) {
                        if lo < 0 {
                                lo = i
@@ -393,12 +393,12 @@ func mkCharClass(f func(int) bool) string {
        return dump(re)
 }
 
-func isUpperFold(rune int) bool {
-       if unicode.IsUpper(rune) {
+func isUpperFold(r rune) bool {
+       if unicode.IsUpper(r) {
                return true
        }
-       c := unicode.SimpleFold(rune)
-       for c != rune {
+       c := unicode.SimpleFold(r)
+       for c != r {
                if unicode.IsUpper(c) {
                        return true
                }
@@ -408,8 +408,8 @@ func isUpperFold(rune int) bool {
 }
 
 func TestFoldConstants(t *testing.T) {
-       last := -1
-       for i := 0; i <= unicode.MaxRune; i++ {
+       last := rune(-1)
+       for i := rune(0); i <= unicode.MaxRune; i++ {
                if unicode.SimpleFold(i) == i {
                        continue
                }
@@ -428,8 +428,8 @@ func TestAppendRangeCollapse(t *testing.T) {
        // into the earlier ones (it looks back two ranges), so that
        // the slice never grows very large.
        // Note that we are not calling cleanClass.
-       var r []int
-       for i := 'A'; i <= 'Z'; i++ {
+       var r []rune
+       for i := rune('A'); i <= 'Z'; i++ {
                r = AppendRange(r, i, i)
                r = AppendRange(r, i+'a'-'A', i+'a'-'A')
        }
index 05b392c..1a11ca6 100644 (file)
@@ -3,17 +3,17 @@
 
 package syntax
 
-var code1 = []int{ /* \d */
+var code1 = []rune{ /* \d */
        0x30, 0x39,
 }
 
-var code2 = []int{ /* \s */
+var code2 = []rune{ /* \s */
        0x9, 0xa,
        0xc, 0xd,
        0x20, 0x20,
 }
 
-var code3 = []int{ /* \w */
+var code3 = []rune{ /* \w */
        0x30, 0x39,
        0x41, 0x5a,
        0x5f, 0x5f,
@@ -28,71 +28,71 @@ var perlGroup = map[string]charGroup{
        `\w`: {+1, code3},
        `\W`: {-1, code3},
 }
-var code4 = []int{ /* [:alnum:] */
+var code4 = []rune{ /* [:alnum:] */
        0x30, 0x39,
        0x41, 0x5a,
        0x61, 0x7a,
 }
 
-var code5 = []int{ /* [:alpha:] */
+var code5 = []rune{ /* [:alpha:] */
        0x41, 0x5a,
        0x61, 0x7a,
 }
 
-var code6 = []int{ /* [:ascii:] */
+var code6 = []rune{ /* [:ascii:] */
        0x0, 0x7f,
 }
 
-var code7 = []int{ /* [:blank:] */
+var code7 = []rune{ /* [:blank:] */
        0x9, 0x9,
        0x20, 0x20,
 }
 
-var code8 = []int{ /* [:cntrl:] */
+var code8 = []rune{ /* [:cntrl:] */
        0x0, 0x1f,
        0x7f, 0x7f,
 }
 
-var code9 = []int{ /* [:digit:] */
+var code9 = []rune{ /* [:digit:] */
        0x30, 0x39,
 }
 
-var code10 = []int{ /* [:graph:] */
+var code10 = []rune{ /* [:graph:] */
        0x21, 0x7e,
 }
 
-var code11 = []int{ /* [:lower:] */
+var code11 = []rune{ /* [:lower:] */
        0x61, 0x7a,
 }
 
-var code12 = []int{ /* [:print:] */
+var code12 = []rune{ /* [:print:] */
        0x20, 0x7e,
 }
 
-var code13 = []int{ /* [:punct:] */
+var code13 = []rune{ /* [:punct:] */
        0x21, 0x2f,
        0x3a, 0x40,
        0x5b, 0x60,
        0x7b, 0x7e,
 }
 
-var code14 = []int{ /* [:space:] */
+var code14 = []rune{ /* [:space:] */
        0x9, 0xd,
        0x20, 0x20,
 }
 
-var code15 = []int{ /* [:upper:] */
+var code15 = []rune{ /* [:upper:] */
        0x41, 0x5a,
 }
 
-var code16 = []int{ /* [:word:] */
+var code16 = []rune{ /* [:word:] */
        0x30, 0x39,
        0x41, 0x5a,
        0x5f, 0x5f,
        0x61, 0x7a,
 }
 
-var code17 = []int{ /* [:xdigit:] */
+var code17 = []rune{ /* [:xdigit:] */
        0x30, 0x39,
        0x41, 0x46,
        0x61, 0x66,
index ced45da..f5b697a 100644 (file)
@@ -51,7 +51,7 @@ const (
 // at the beginning of the text.
 // Passing r2 == -1 indicates that the position is
 // at the end of the text.
-func EmptyOpContext(r1, r2 int) EmptyOp {
+func EmptyOpContext(r1, r2 rune) EmptyOp {
        var op EmptyOp
        if r1 < 0 {
                op |= EmptyBeginText | EmptyBeginLine
@@ -76,7 +76,7 @@ func EmptyOpContext(r1, r2 int) EmptyOp {
 // IsWordChar reports whether r is consider a ``word character''
 // during the evaluation of the \b and \B zero-width assertions.
 // These assertions are ASCII-only: the word characters are [A-Za-z0-9_].
-func IsWordChar(r int) bool {
+func IsWordChar(r rune) bool {
        return 'A' <= r && r <= 'Z' || 'a' <= r && r <= 'z' || '0' <= r && r <= '9' || r == '_'
 }
 
@@ -85,7 +85,7 @@ type Inst struct {
        Op   InstOp
        Out  uint32 // all but InstMatch, InstFail
        Arg  uint32 // InstAlt, InstAltMatch, InstCapture, InstEmptyWidth
-       Rune []int
+       Rune []rune
 }
 
 func (p *Prog) String() string {
@@ -161,7 +161,7 @@ Loop:
 
 // MatchRune returns true if the instruction matches (and consumes) r.
 // It should only be called when i.Op == InstRune.
-func (i *Inst) MatchRune(r int) bool {
+func (i *Inst) MatchRune(r rune) bool {
        rune := i.Rune
 
        // Special case: single-rune slice is from literal string, not char class.
@@ -210,17 +210,17 @@ func (i *Inst) MatchRune(r int) bool {
 
 // As per re2's Prog::IsWordChar. Determines whether rune is an ASCII word char.
 // Since we act on runes, it would be easy to support Unicode here.
-func wordRune(rune int) bool {
-       return rune == '_' ||
-               ('A' <= rune && rune <= 'Z') ||
-               ('a' <= rune && rune <= 'z') ||
-               ('0' <= rune && rune <= '9')
+func wordRune(r rune) bool {
+       return r == '_' ||
+               ('A' <= r && r <= 'Z') ||
+               ('a' <= r && r <= 'z') ||
+               ('0' <= r && r <= '9')
 }
 
 // MatchEmptyWidth returns true if the instruction matches
 // an empty string between the runes before and after.
 // It should only be called when i.Op == InstEmptyWidth.
-func (i *Inst) MatchEmptyWidth(before int, after int) bool {
+func (i *Inst) MatchEmptyWidth(before rune, after rune) bool {
        switch EmptyOp(i.Arg) {
        case EmptyBeginLine:
                return before == '\n' || before == -1
index 033848d..b5ddab1 100644 (file)
@@ -22,8 +22,8 @@ type Regexp struct {
        Flags    Flags
        Sub      []*Regexp  // subexpressions, if any
        Sub0     [1]*Regexp // storage for short Sub
-       Rune     []int      // matched runes, for OpLiteral, OpCharClass
-       Rune0    [2]int     // storage for short Rune
+       Rune     []rune     // matched runes, for OpLiteral, OpCharClass
+       Rune0    [2]rune    // storage for short Rune
        Min, Max int        // min, max for OpRepeat
        Cap      int        // capturing index, for OpCapture
        Name     string     // capturing name, for OpCapture
@@ -252,7 +252,7 @@ func (re *Regexp) String() string {
 
 const meta = `\.+*?()|[]{}^$`
 
-func escape(b *bytes.Buffer, r int, force bool) {
+func escape(b *bytes.Buffer, r rune, force bool) {
        if unicode.IsPrint(r) {
                if strings.IndexRune(meta, r) >= 0 || force {
                        b.WriteRune('\\')
@@ -277,7 +277,7 @@ func escape(b *bytes.Buffer, r int, force bool) {
        default:
                if r < 0x100 {
                        b.WriteString(`\x`)
-                       s := strconv.Itob(r, 16)
+                       s := strconv.Itob(int(r), 16)
                        if len(s) == 1 {
                                b.WriteRune('0')
                        }
@@ -285,7 +285,7 @@ func escape(b *bytes.Buffer, r int, force bool) {
                        break
                }
                b.WriteString(`\x{`)
-               b.WriteString(strconv.Itob(r, 16))
+               b.WriteString(strconv.Itob(int(r), 16))
                b.WriteString(`}`)
        }
 }
index c1a9e8e..99253ba 100644 (file)
@@ -6,6 +6,7 @@ package jsonrpc
 
 import (
        "fmt"
+       "io"
        "json"
        "net"
        "os"
@@ -154,3 +155,67 @@ func TestClient(t *testing.T) {
                t.Error("Div: expected divide by zero error; got", err)
        }
 }
+
+func TestMalformedInput(t *testing.T) {
+       cli, srv := net.Pipe()
+       go cli.Write([]byte(`{id:1}`)) // invalid json
+       ServeConn(srv)                 // must return, not loop
+}
+
+func TestUnexpectedError(t *testing.T) {
+       cli, srv := myPipe()
+       go cli.PipeWriter.CloseWithError(os.NewError("unexpected error!")) // reader will get this error
+       ServeConn(srv)                                                     // must return, not loop
+}
+
+// Copied from package net.
+func myPipe() (*pipe, *pipe) {
+       r1, w1 := io.Pipe()
+       r2, w2 := io.Pipe()
+
+       return &pipe{r1, w2}, &pipe{r2, w1}
+}
+
+type pipe struct {
+       *io.PipeReader
+       *io.PipeWriter
+}
+
+type pipeAddr int
+
+func (pipeAddr) Network() string {
+       return "pipe"
+}
+
+func (pipeAddr) String() string {
+       return "pipe"
+}
+
+func (p *pipe) Close() os.Error {
+       err := p.PipeReader.Close()
+       err1 := p.PipeWriter.Close()
+       if err == nil {
+               err = err1
+       }
+       return err
+}
+
+func (p *pipe) LocalAddr() net.Addr {
+       return pipeAddr(0)
+}
+
+func (p *pipe) RemoteAddr() net.Addr {
+       return pipeAddr(0)
+}
+
+func (p *pipe) SetTimeout(nsec int64) os.Error {
+       return os.NewError("net.Pipe does not support timeouts")
+}
+
+func (p *pipe) SetReadTimeout(nsec int64) os.Error {
+       return os.NewError("net.Pipe does not support timeouts")
+}
+
+func (p *pipe) SetWriteTimeout(nsec int64) os.Error {
+       return os.NewError("net.Pipe does not support timeouts")
+}
index f037100..71797e2 100644 (file)
@@ -116,8 +116,8 @@ import (
        "bufio"
        "gob"
        "http"
-       "log"
        "io"
+       "log"
        "net"
        "os"
        "reflect"
@@ -394,12 +394,12 @@ func (server *Server) ServeConn(conn io.ReadWriteCloser) {
 func (server *Server) ServeCodec(codec ServerCodec) {
        sending := new(sync.Mutex)
        for {
-               service, mtype, req, argv, replyv, err := server.readRequest(codec)
+               service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
                if err != nil {
                        if err != os.EOF {
                                log.Println("rpc:", err)
                        }
-                       if err == os.EOF || err == io.ErrUnexpectedEOF {
+                       if !keepReading {
                                break
                        }
                        // send a response if we actually managed to read a header.
@@ -418,9 +418,9 @@ func (server *Server) ServeCodec(codec ServerCodec) {
 // It does not close the codec upon completion.
 func (server *Server) ServeRequest(codec ServerCodec) os.Error {
        sending := new(sync.Mutex)
-       service, mtype, req, argv, replyv, err := server.readRequest(codec)
+       service, mtype, req, argv, replyv, keepReading, err := server.readRequest(codec)
        if err != nil {
-               if err == os.EOF || err == io.ErrUnexpectedEOF {
+               if !keepReading {
                        return err
                }
                // send a response if we actually managed to read a header.
@@ -474,10 +474,10 @@ func (server *Server) freeResponse(resp *Response) {
        server.respLock.Unlock()
 }
 
-func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, err os.Error) {
-       service, mtype, req, err = server.readRequestHeader(codec)
+func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *methodType, req *Request, argv, replyv reflect.Value, keepReading bool, err os.Error) {
+       service, mtype, req, keepReading, err = server.readRequestHeader(codec)
        if err != nil {
-               if err == os.EOF || err == io.ErrUnexpectedEOF {
+               if !keepReading {
                        return
                }
                // discard body
@@ -505,7 +505,7 @@ func (server *Server) readRequest(codec ServerCodec) (service *service, mtype *m
        return
 }
 
-func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mtype *methodType, req *Request, err os.Error) {
+func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mtype *methodType, req *Request, keepReading bool, err os.Error) {
        // Grab the request header.
        req = server.getRequest()
        err = codec.ReadRequestHeader(req)
@@ -518,6 +518,10 @@ func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mt
                return
        }
 
+       // We read the header successfully.  If we see an error now,
+       // we can still recover and move on to the next request.
+       keepReading = true
+
        serviceMethod := strings.Split(req.ServiceMethod, ".")
        if len(serviceMethod) != 2 {
                err = os.NewError("rpc: service/method request ill-formed: " + req.ServiceMethod)
index 029741b..3e9fe29 100644 (file)
@@ -311,8 +311,9 @@ func (codec *CodecEmulator) ReadRequestBody(argv interface{}) os.Error {
 func (codec *CodecEmulator) WriteResponse(resp *Response, reply interface{}) os.Error {
        if resp.Error != "" {
                codec.err = os.NewError(resp.Error)
+       } else {
+               *codec.reply = *(reply.(*Reply))
        }
-       *codec.reply = *(reply.(*Reply))
        return nil
 }
 
index 6370a57..1243703 100644 (file)
@@ -10,7 +10,6 @@ func Breakpoint()
 // LockOSThread wires the calling goroutine to its current operating system thread.
 // Until the calling goroutine exits or calls UnlockOSThread, it will always
 // execute in that thread, and no other goroutine can.
-// LockOSThread cannot be used during init functions.
 func LockOSThread()
 
 // UnlockOSThread unwires the calling goroutine from its fixed operating system thread.
index fdeceb4..7022896 100644 (file)
@@ -17,6 +17,9 @@ import (
        "sync"
 )
 
+// BUG(rsc): CPU profiling is broken on OS X, due to an Apple kernel bug.
+// For details, see http://code.google.com/p/go/source/detail?r=35b716c94225.
+
 // WriteHeapProfile writes a pprof-formatted heap profile to w.
 // If a write to w returns an error, WriteHeapProfile returns that error.
 // Otherwise, WriteHeapProfile returns nil.
index 29e5f8c..3594db9 100644 (file)
@@ -93,7 +93,7 @@ const (
        skipComment
 )
 
-var tokenString = map[int]string{
+var tokenString = map[rune]string{
        EOF:       "EOF",
        Ident:     "Ident",
        Int:       "Int",
@@ -105,7 +105,7 @@ var tokenString = map[int]string{
 }
 
 // TokenString returns a (visible) string for a token or Unicode character.
-func TokenString(tok int) string {
+func TokenString(tok rune) string {
        if s, found := tokenString[tok]; found {
                return s
        }
@@ -144,7 +144,7 @@ type Scanner struct {
        tokEnd int          // token text tail end (srcBuf index)
 
        // One character look-ahead
-       ch int // character before current srcPos
+       ch rune // character before current srcPos
 
        // Error is called for each error encountered. If no Error
        // function is set, the error is reported to os.Stderr.
@@ -218,8 +218,8 @@ func (s *Scanner) Init(src io.Reader) *Scanner {
 // that only a minimal amount of work needs to be done in the common ASCII
 // case (one test to check for both ASCII and end-of-buffer, and one test
 // to check for newlines).
-func (s *Scanner) next() int {
-       ch, width := int(s.srcBuf[s.srcPos]), 1
+func (s *Scanner) next() rune {
+       ch, width := rune(s.srcBuf[s.srcPos]), 1
 
        if ch >= utf8.RuneSelf {
                // uncommon case: not ASCII or not enough bytes
@@ -264,7 +264,7 @@ func (s *Scanner) next() int {
                        }
                }
                // at least one byte
-               ch = int(s.srcBuf[s.srcPos])
+               ch = rune(s.srcBuf[s.srcPos])
                if ch >= utf8.RuneSelf {
                        // uncommon case: not ASCII
                        ch, width = utf8.DecodeRune(s.srcBuf[s.srcPos:s.srcEnd])
@@ -304,7 +304,7 @@ func (s *Scanner) next() int {
 // it prints an error message to os.Stderr. Next does not
 // update the Scanner's Position field; use Pos() to
 // get the current position.
-func (s *Scanner) Next() int {
+func (s *Scanner) Next() rune {
        s.tokPos = -1 // don't collect token text
        s.Line = 0    // invalidate token position
        ch := s.Peek()
@@ -315,7 +315,7 @@ func (s *Scanner) Next() int {
 // Peek returns the next Unicode character in the source without advancing
 // the scanner. It returns EOF if the scanner's position is at the last
 // character of the source.
-func (s *Scanner) Peek() int {
+func (s *Scanner) Peek() rune {
        if s.ch < 0 {
                s.ch = s.next()
        }
@@ -335,7 +335,7 @@ func (s *Scanner) error(msg string) {
        fmt.Fprintf(os.Stderr, "%s: %s\n", pos, msg)
 }
 
-func (s *Scanner) scanIdentifier() int {
+func (s *Scanner) scanIdentifier() rune {
        ch := s.next() // read character after first '_' or letter
        for ch == '_' || unicode.IsLetter(ch) || unicode.IsDigit(ch) {
                ch = s.next()
@@ -343,35 +343,35 @@ func (s *Scanner) scanIdentifier() int {
        return ch
 }
 
-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
 }
 
-func isDecimal(ch int) bool { return '0' <= ch && ch <= '9' }
+func isDecimal(ch rune) bool { return '0' <= ch && ch <= '9' }
 
-func (s *Scanner) scanMantissa(ch int) int {
+func (s *Scanner) scanMantissa(ch rune) rune {
        for isDecimal(ch) {
                ch = s.next()
        }
        return ch
 }
 
-func (s *Scanner) scanFraction(ch int) int {
+func (s *Scanner) scanFraction(ch rune) rune {
        if ch == '.' {
                ch = s.scanMantissa(s.next())
        }
        return ch
 }
 
-func (s *Scanner) scanExponent(ch int) int {
+func (s *Scanner) scanExponent(ch rune) rune {
        if ch == 'e' || ch == 'E' {
                ch = s.next()
                if ch == '-' || ch == '+' {
@@ -382,7 +382,7 @@ func (s *Scanner) scanExponent(ch int) int {
        return ch
 }
 
-func (s *Scanner) scanNumber(ch int) (int, int) {
+func (s *Scanner) scanNumber(ch rune) (rune, rune) {
        // isDecimal(ch)
        if ch == '0' {
                // int or float
@@ -426,7 +426,7 @@ func (s *Scanner) scanNumber(ch int) (int, int) {
        return Int, ch
 }
 
-func (s *Scanner) scanDigits(ch, base, n int) int {
+func (s *Scanner) scanDigits(ch rune, base, n int) rune {
        for n > 0 && digitVal(ch) < base {
                ch = s.next()
                n--
@@ -437,7 +437,7 @@ func (s *Scanner) scanDigits(ch, base, n int) int {
        return ch
 }
 
-func (s *Scanner) scanEscape(quote int) int {
+func (s *Scanner) scanEscape(quote rune) rune {
        ch := s.next() // read character after '/'
        switch ch {
        case 'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', quote:
@@ -457,7 +457,7 @@ func (s *Scanner) scanEscape(quote int) int {
        return ch
 }
 
-func (s *Scanner) scanString(quote int) (n int) {
+func (s *Scanner) scanString(quote rune) (n int) {
        ch := s.next() // read character after quote
        for ch != quote {
                if ch == '\n' || ch < 0 {
@@ -491,7 +491,7 @@ func (s *Scanner) scanChar() {
        }
 }
 
-func (s *Scanner) scanComment(ch int) int {
+func (s *Scanner) scanComment(ch rune) rune {
        // ch == '/' || ch == '*'
        if ch == '/' {
                // line comment
@@ -524,7 +524,7 @@ func (s *Scanner) scanComment(ch int) int {
 // It returns EOF at the end of the source. It reports scanner errors (read and
 // token errors) by calling s.Error, if not nil; otherwise it prints an error
 // message to os.Stderr.
-func (s *Scanner) Scan() int {
+func (s *Scanner) Scan() rune {
        ch := s.Peek()
 
        // reset token text position
index bbbba12..fb39883 100644 (file)
@@ -64,7 +64,7 @@ func TestNext(t *testing.T) {
 }
 
 type token struct {
-       tok  int
+       tok  rune
        text string
 }
 
@@ -233,7 +233,7 @@ func makeSource(pattern string) *bytes.Buffer {
        return &buf
 }
 
-func checkTok(t *testing.T, s *Scanner, line, got, want int, text string) {
+func checkTok(t *testing.T, s *Scanner, line int, got, want rune, text string) {
        if got != want {
                t.Fatalf("tok = %s, want %s for %q", TokenString(got), TokenString(want), text)
        }
@@ -329,7 +329,7 @@ func TestScanZeroMode(t *testing.T) {
        }
 }
 
-func testScanSelectedMode(t *testing.T, mode uint, class int) {
+func testScanSelectedMode(t *testing.T, mode uint, class rune) {
        src := makeSource("%s\n")
        s := new(Scanner).Init(src)
        s.Mode = mode
@@ -398,7 +398,7 @@ func TestScanWhitespace(t *testing.T) {
        }
 }
 
-func testError(t *testing.T, src, pos, msg string, tok int) {
+func testError(t *testing.T, src, pos, msg string, tok rune) {
        s := new(Scanner).Init(bytes.NewBufferString(src))
        errorCalled := false
        s.Error = func(s *Scanner, m string) {
@@ -463,7 +463,7 @@ func checkPos(t *testing.T, got, want Position) {
        }
 }
 
-func checkNextPos(t *testing.T, s *Scanner, offset, line, column, char int) {
+func checkNextPos(t *testing.T, s *Scanner, offset, line, column int, char rune) {
        if ch := s.Next(); ch != char {
                t.Errorf("ch = %s, want %s", TokenString(ch), TokenString(char))
        }
@@ -471,7 +471,7 @@ func checkNextPos(t *testing.T, s *Scanner, offset, line, column, char int) {
        checkPos(t, s.Pos(), want)
 }
 
-func checkScanPos(t *testing.T, s *Scanner, offset, line, column, char int) {
+func checkScanPos(t *testing.T, s *Scanner, offset, line, column int, char rune) {
        want := Position{Offset: offset, Line: line, Column: column}
        checkPos(t, s.Pos(), want)
        if ch := s.Scan(); ch != char {
index c053557..553d3ae 100644 (file)
@@ -37,14 +37,14 @@ testLoop:
                        t.Errorf("#%d got response %s, expected %s", i, resp, test.responses[0])
                }
                if err != nil {
-                       t.Errorf("#%d error: %s", i, err.String())
+                       t.Errorf("#%d error: %s", i, err)
                }
                for j := range test.challenges {
                        challenge := []byte(test.challenges[j])
                        expected := []byte(test.responses[j+1])
                        resp, err := test.auth.Next(challenge, true)
                        if err != nil {
-                               t.Errorf("#%d error: %s", i, err.String())
+                               t.Errorf("#%d error: %s", i, err)
                                continue testLoop
                        }
                        if !bytes.Equal(resp, expected) {
@@ -74,13 +74,13 @@ func TestBasic(t *testing.T) {
        c := &Client{Text: textproto.NewConn(fake)}
 
        if err := c.helo(); err != nil {
-               t.Fatalf("HELO failed: %s", err.String())
+               t.Fatalf("HELO failed: %s", err)
        }
        if err := c.ehlo(); err == nil {
                t.Fatalf("Expected first EHLO to fail")
        }
        if err := c.ehlo(); err != nil {
-               t.Fatalf("Second EHLO failed: %s", err.String())
+               t.Fatalf("Second EHLO failed: %s", err)
        }
 
        if ok, args := c.Extension("aUtH"); !ok || args != "LOGIN PLAIN" {
@@ -105,14 +105,14 @@ func TestBasic(t *testing.T) {
        c.tls = true
        c.serverName = "smtp.google.com"
        if err := c.Auth(PlainAuth("", "user", "pass", "smtp.google.com")); err != nil {
-               t.Fatalf("AUTH failed: %s", err.String())
+               t.Fatalf("AUTH failed: %s", err)
        }
 
        if err := c.Mail("user@gmail.com"); err != nil {
-               t.Fatalf("MAIL failed: %s", err.String())
+               t.Fatalf("MAIL failed: %s", err)
        }
        if err := c.Rcpt("golang-nuts@googlegroups.com"); err != nil {
-               t.Fatalf("RCPT failed: %s", err.String())
+               t.Fatalf("RCPT failed: %s", err)
        }
        msg := `From: user@gmail.com
 To: golang-nuts@googlegroups.com
@@ -123,17 +123,17 @@ Line 1
 Goodbye.`
        w, err := c.Data()
        if err != nil {
-               t.Fatalf("DATA failed: %s", err.String())
+               t.Fatalf("DATA failed: %s", err)
        }
        if _, err := w.Write([]byte(msg)); err != nil {
-               t.Fatalf("Data write failed: %s", err.String())
+               t.Fatalf("Data write failed: %s", err)
        }
        if err := w.Close(); err != nil {
-               t.Fatalf("Bad data response: %s", err.String())
+               t.Fatalf("Bad data response: %s", err)
        }
 
        if err := c.Quit(); err != nil {
-               t.Fatalf("QUIT failed: %s", err.String())
+               t.Fatalf("QUIT failed: %s", err)
        }
 
        bcmdbuf.Flush()
index 98ce750..7208194 100644 (file)
@@ -16,7 +16,7 @@ func Atob(str string) (value bool, err os.Error) {
        case "0", "f", "F", "false", "FALSE", "False":
                return false, nil
        }
-       return false, &NumError{str, os.EINVAL}
+       return false, &NumError{str, ErrSyntax}
 }
 
 // Btoa returns "true" or "false" according to the value of the boolean argument
index 541e60d..d9db6c7 100644 (file)
@@ -17,8 +17,8 @@ type atobTest struct {
 }
 
 var atobtests = []atobTest{
-       {"", false, os.EINVAL},
-       {"asdf", false, os.EINVAL},
+       {"", false, ErrSyntax},
+       {"asdf", false, ErrSyntax},
        {"0", false, nil},
        {"f", false, nil},
        {"F", false, nil},
index 86c56f7..4a4b1b4 100644 (file)
@@ -350,11 +350,11 @@ func (d *decimal) atof32() (f float32, ok bool) {
 // The errors that Atof32 returns have concrete type *NumError
 // and include err.Num = s.
 //
-// If s is not syntactically well-formed, Atof32 returns err.Error = os.EINVAL.
+// If s is not syntactically well-formed, Atof32 returns err.Error = ErrSyntax.
 //
 // If s is syntactically well-formed but is more than 1/2 ULP
 // away from the largest floating point number of the given size,
-// Atof32 returns f = ±Inf, err.Error = os.ERANGE.
+// Atof32 returns f = ±Inf, err.Error = ErrRange.
 func Atof32(s string) (f float32, err os.Error) {
        if val, ok := special(s); ok {
                return float32(val), nil
@@ -362,7 +362,7 @@ func Atof32(s string) (f float32, err os.Error) {
 
        var d decimal
        if !d.set(s) {
-               return 0, &NumError{s, os.EINVAL}
+               return 0, &NumError{s, ErrSyntax}
        }
        if optimize {
                if f, ok := d.atof32(); ok {
@@ -372,7 +372,7 @@ func Atof32(s string) (f float32, err os.Error) {
        b, ovf := d.floatBits(&float32info)
        f = math.Float32frombits(uint32(b))
        if ovf {
-               err = &NumError{s, os.ERANGE}
+               err = &NumError{s, ErrRange}
        }
        return f, err
 }
@@ -387,7 +387,7 @@ func Atof64(s string) (f float64, err os.Error) {
 
        var d decimal
        if !d.set(s) {
-               return 0, &NumError{s, os.EINVAL}
+               return 0, &NumError{s, ErrSyntax}
        }
        if optimize {
                if f, ok := d.atof64(); ok {
@@ -397,7 +397,7 @@ func Atof64(s string) (f float64, err os.Error) {
        b, ovf := d.floatBits(&float64info)
        f = math.Float64frombits(b)
        if ovf {
-               err = &NumError{s, os.ERANGE}
+               err = &NumError{s, ErrRange}
        }
        return f, err
 }
index 23aafc1..33f881c 100644 (file)
@@ -18,11 +18,11 @@ type atofTest struct {
 }
 
 var atoftests = []atofTest{
-       {"", "0", os.EINVAL},
+       {"", "0", ErrSyntax},
        {"1", "1", nil},
        {"+1", "1", nil},
-       {"1x", "0", os.EINVAL},
-       {"1.1.", "0", os.EINVAL},
+       {"1x", "0", ErrSyntax},
+       {"1.1.", "0", ErrSyntax},
        {"1e23", "1e+23", nil},
        {"1E23", "1e+23", nil},
        {"100000000000000000000000", "1e+23", nil},
@@ -56,28 +56,28 @@ var atoftests = []atofTest{
        {"1.7976931348623157e308", "1.7976931348623157e+308", nil},
        {"-1.7976931348623157e308", "-1.7976931348623157e+308", nil},
        // next float64 - too large
-       {"1.7976931348623159e308", "+Inf", os.ERANGE},
-       {"-1.7976931348623159e308", "-Inf", os.ERANGE},
+       {"1.7976931348623159e308", "+Inf", ErrRange},
+       {"-1.7976931348623159e308", "-Inf", ErrRange},
        // the border is ...158079
        // borderline - okay
        {"1.7976931348623158e308", "1.7976931348623157e+308", nil},
        {"-1.7976931348623158e308", "-1.7976931348623157e+308", nil},
        // borderline - too large
-       {"1.797693134862315808e308", "+Inf", os.ERANGE},
-       {"-1.797693134862315808e308", "-Inf", os.ERANGE},
+       {"1.797693134862315808e308", "+Inf", ErrRange},
+       {"-1.797693134862315808e308", "-Inf", ErrRange},
 
        // a little too large
        {"1e308", "1e+308", nil},
-       {"2e308", "+Inf", os.ERANGE},
-       {"1e309", "+Inf", os.ERANGE},
+       {"2e308", "+Inf", ErrRange},
+       {"1e309", "+Inf", ErrRange},
 
        // way too large
-       {"1e310", "+Inf", os.ERANGE},
-       {"-1e310", "-Inf", os.ERANGE},
-       {"1e400", "+Inf", os.ERANGE},
-       {"-1e400", "-Inf", os.ERANGE},
-       {"1e400000", "+Inf", os.ERANGE},
-       {"-1e400000", "-Inf", os.ERANGE},
+       {"1e310", "+Inf", ErrRange},
+       {"-1e310", "-Inf", ErrRange},
+       {"1e400", "+Inf", ErrRange},
+       {"-1e400", "-Inf", ErrRange},
+       {"1e400000", "+Inf", ErrRange},
+       {"-1e400000", "-Inf", ErrRange},
 
        // denormalized
        {"1e-305", "1e-305", nil},
@@ -99,14 +99,14 @@ var atoftests = []atofTest{
 
        // try to overflow exponent
        {"1e-4294967296", "0", nil},
-       {"1e+4294967296", "+Inf", os.ERANGE},
+       {"1e+4294967296", "+Inf", ErrRange},
        {"1e-18446744073709551616", "0", nil},
-       {"1e+18446744073709551616", "+Inf", os.ERANGE},
+       {"1e+18446744073709551616", "+Inf", ErrRange},
 
        // Parse errors
-       {"1e", "0", os.EINVAL},
-       {"1e-", "0", os.EINVAL},
-       {".e-1", "0", os.EINVAL},
+       {"1e", "0", ErrSyntax},
+       {"1e-", "0", ErrSyntax},
+       {".e-1", "0", ErrSyntax},
 
        // http://www.exploringbinary.com/java-hangs-when-converting-2-2250738585072012e-308/
        {"2.2250738585072012e-308", "2.2250738585072014e-308", nil},
index 5845942..92ba89d 100644 (file)
@@ -6,9 +6,16 @@ package strconv
 
 import "os"
 
+// ErrRange indicates that a value is out of range for the target type.
+var ErrRange = os.NewError("value out of range")
+
+// ErrSyntax indicates that a value does not have the right syntax for the target type.
+var ErrSyntax = os.NewError("invalid syntax")
+
+// A NumError records a failed conversion.
 type NumError struct {
-       Num   string
-       Error os.Error
+       Num   string   // the input
+       Error os.Error // the reason the conversion failed (ErrRange, ErrSyntax)
 }
 
 func (e *NumError) String() string { return `parsing "` + e.Num + `": ` + e.Error.String() }
@@ -38,15 +45,15 @@ func cutoff64(base int) uint64 {
 //
 // The errors that Btoui64 returns have concrete type *NumError
 // and include err.Num = s.  If s is empty or contains invalid
-// digits, err.Error = os.EINVAL; if the value corresponding
-// to s cannot be represented by a uint64, err.Error = os.ERANGE.
+// digits, err.Error = ErrSyntax; if the value corresponding
+// to s cannot be represented by a uint64, err.Error = ErrRange.
 func Btoui64(s string, b int) (n uint64, err os.Error) {
        var cutoff uint64
 
        s0 := s
        switch {
        case len(s) < 1:
-               err = os.EINVAL
+               err = ErrSyntax
                goto Error
 
        case 2 <= b && b <= 36:
@@ -59,7 +66,7 @@ func Btoui64(s string, b int) (n uint64, err os.Error) {
                        b = 16
                        s = s[2:]
                        if len(s) < 1 {
-                               err = os.EINVAL
+                               err = ErrSyntax
                                goto Error
                        }
                case s[0] == '0':
@@ -88,19 +95,19 @@ func Btoui64(s string, b int) (n uint64, err os.Error) {
                        v = d - 'A' + 10
                default:
                        n = 0
-                       err = os.EINVAL
+                       err = ErrSyntax
                        goto Error
                }
                if int(v) >= b {
                        n = 0
-                       err = os.EINVAL
+                       err = ErrSyntax
                        goto Error
                }
 
                if n >= cutoff {
                        // n*b overflows
                        n = 1<<64 - 1
-                       err = os.ERANGE
+                       err = ErrRange
                        goto Error
                }
                n *= uint64(b)
@@ -109,7 +116,7 @@ func Btoui64(s string, b int) (n uint64, err os.Error) {
                if n1 < n {
                        // n+v overflows
                        n = 1<<64 - 1
-                       err = os.ERANGE
+                       err = ErrRange
                        goto Error
                }
                n = n1
@@ -124,8 +131,8 @@ Error:
 // Atoui64 interprets a string s as a decimal number and
 // returns the corresponding value n.
 //
-// Atoui64 returns err == os.EINVAL if s is empty or contains invalid digits.
-// It returns err == os.ERANGE if s cannot be represented by a uint64.
+// Atoui64 returns err.Error = ErrSyntax if s is empty or contains invalid digits.
+// It returns err.Error = ErrRange if s cannot be represented by a uint64.
 func Atoui64(s string) (n uint64, err os.Error) {
        return Btoui64(s, 10)
 }
@@ -135,7 +142,7 @@ func Atoui64(s string) (n uint64, err os.Error) {
 func Btoi64(s string, base int) (i int64, err os.Error) {
        // Empty string bad.
        if len(s) == 0 {
-               return 0, &NumError{s, os.EINVAL}
+               return 0, &NumError{s, ErrSyntax}
        }
 
        // Pick off leading sign.
@@ -151,15 +158,15 @@ func Btoi64(s string, base int) (i int64, err os.Error) {
        // Convert unsigned and check range.
        var un uint64
        un, err = Btoui64(s, base)
-       if err != nil && err.(*NumError).Error != os.ERANGE {
+       if err != nil && err.(*NumError).Error != ErrRange {
                err.(*NumError).Num = s0
                return 0, err
        }
        if !neg && un >= 1<<63 {
-               return 1<<63 - 1, &NumError{s0, os.ERANGE}
+               return 1<<63 - 1, &NumError{s0, ErrRange}
        }
        if neg && un > 1<<63 {
-               return -1 << 63, &NumError{s0, os.ERANGE}
+               return -1 << 63, &NumError{s0, ErrRange}
        }
        n := int64(un)
        if neg {
@@ -175,12 +182,12 @@ func Atoi64(s string) (i int64, err os.Error) { return Btoi64(s, 10) }
 // Atoui is like Atoui64 but returns its result as a uint.
 func Atoui(s string) (i uint, err os.Error) {
        i1, e1 := Atoui64(s)
-       if e1 != nil && e1.(*NumError).Error != os.ERANGE {
+       if e1 != nil && e1.(*NumError).Error != ErrRange {
                return 0, e1
        }
        i = uint(i1)
        if uint64(i) != i1 {
-               return ^uint(0), &NumError{s, os.ERANGE}
+               return ^uint(0), &NumError{s, ErrRange}
        }
        return i, nil
 }
@@ -188,15 +195,15 @@ func Atoui(s string) (i uint, err os.Error) {
 // Atoi is like Atoi64 but returns its result as an int.
 func Atoi(s string) (i int, err os.Error) {
        i1, e1 := Atoi64(s)
-       if e1 != nil && e1.(*NumError).Error != os.ERANGE {
+       if e1 != nil && e1.(*NumError).Error != ErrRange {
                return 0, e1
        }
        i = int(i1)
        if int64(i) != i1 {
                if i1 < 0 {
-                       return -1 << (IntSize - 1), &NumError{s, os.ERANGE}
+                       return -1 << (IntSize - 1), &NumError{s, ErrRange}
                }
-               return 1<<(IntSize-1) - 1, &NumError{s, os.ERANGE}
+               return 1<<(IntSize-1) - 1, &NumError{s, ErrRange}
        }
        return i, nil
 }
index 0b9f295..0d2e381 100644 (file)
@@ -18,36 +18,36 @@ type atoui64Test struct {
 }
 
 var atoui64tests = []atoui64Test{
-       {"", 0, os.EINVAL},
+       {"", 0, ErrSyntax},
        {"0", 0, nil},
        {"1", 1, nil},
        {"12345", 12345, nil},
        {"012345", 12345, nil},
-       {"12345x", 0, os.EINVAL},
+       {"12345x", 0, ErrSyntax},
        {"98765432100", 98765432100, nil},
        {"18446744073709551615", 1<<64 - 1, nil},
-       {"18446744073709551616", 1<<64 - 1, os.ERANGE},
-       {"18446744073709551620", 1<<64 - 1, os.ERANGE},
+       {"18446744073709551616", 1<<64 - 1, ErrRange},
+       {"18446744073709551620", 1<<64 - 1, ErrRange},
 }
 
 var btoui64tests = []atoui64Test{
-       {"", 0, os.EINVAL},
+       {"", 0, ErrSyntax},
        {"0", 0, nil},
        {"1", 1, nil},
        {"12345", 12345, nil},
        {"012345", 012345, nil},
        {"0x12345", 0x12345, nil},
        {"0X12345", 0x12345, nil},
-       {"12345x", 0, os.EINVAL},
+       {"12345x", 0, ErrSyntax},
        {"98765432100", 98765432100, nil},
        {"18446744073709551615", 1<<64 - 1, nil},
-       {"18446744073709551616", 1<<64 - 1, os.ERANGE},
-       {"18446744073709551620", 1<<64 - 1, os.ERANGE},
+       {"18446744073709551616", 1<<64 - 1, ErrRange},
+       {"18446744073709551620", 1<<64 - 1, ErrRange},
        {"0xFFFFFFFFFFFFFFFF", 1<<64 - 1, nil},
-       {"0x10000000000000000", 1<<64 - 1, os.ERANGE},
+       {"0x10000000000000000", 1<<64 - 1, ErrRange},
        {"01777777777777777777777", 1<<64 - 1, nil},
-       {"01777777777777777777778", 0, os.EINVAL},
-       {"02000000000000000000000", 1<<64 - 1, os.ERANGE},
+       {"01777777777777777777778", 0, ErrSyntax},
+       {"02000000000000000000000", 1<<64 - 1, ErrRange},
        {"0200000000000000000000", 1 << 61, nil},
 }
 
@@ -58,7 +58,7 @@ type atoi64Test struct {
 }
 
 var atoi64tests = []atoi64Test{
-       {"", 0, os.EINVAL},
+       {"", 0, ErrSyntax},
        {"0", 0, nil},
        {"-0", 0, nil},
        {"1", 1, nil},
@@ -71,14 +71,14 @@ var atoi64tests = []atoi64Test{
        {"-98765432100", -98765432100, nil},
        {"9223372036854775807", 1<<63 - 1, nil},
        {"-9223372036854775807", -(1<<63 - 1), nil},
-       {"9223372036854775808", 1<<63 - 1, os.ERANGE},
+       {"9223372036854775808", 1<<63 - 1, ErrRange},
        {"-9223372036854775808", -1 << 63, nil},
-       {"9223372036854775809", 1<<63 - 1, os.ERANGE},
-       {"-9223372036854775809", -1 << 63, os.ERANGE},
+       {"9223372036854775809", 1<<63 - 1, ErrRange},
+       {"-9223372036854775809", -1 << 63, ErrRange},
 }
 
 var btoi64tests = []atoi64Test{
-       {"", 0, os.EINVAL},
+       {"", 0, ErrSyntax},
        {"0", 0, nil},
        {"-0", 0, nil},
        {"1", 1, nil},
@@ -89,16 +89,16 @@ var btoi64tests = []atoi64Test{
        {"-012345", -012345, nil},
        {"0x12345", 0x12345, nil},
        {"-0X12345", -0x12345, nil},
-       {"12345x", 0, os.EINVAL},
-       {"-12345x", 0, os.EINVAL},
+       {"12345x", 0, ErrSyntax},
+       {"-12345x", 0, ErrSyntax},
        {"98765432100", 98765432100, nil},
        {"-98765432100", -98765432100, nil},
        {"9223372036854775807", 1<<63 - 1, nil},
        {"-9223372036854775807", -(1<<63 - 1), nil},
-       {"9223372036854775808", 1<<63 - 1, os.ERANGE},
+       {"9223372036854775808", 1<<63 - 1, ErrRange},
        {"-9223372036854775808", -1 << 63, nil},
-       {"9223372036854775809", 1<<63 - 1, os.ERANGE},
-       {"-9223372036854775809", -1 << 63, os.ERANGE},
+       {"9223372036854775809", 1<<63 - 1, ErrRange},
+       {"-9223372036854775809", -1 << 63, ErrRange},
 }
 
 type atoui32Test struct {
@@ -108,15 +108,15 @@ type atoui32Test struct {
 }
 
 var atoui32tests = []atoui32Test{
-       {"", 0, os.EINVAL},
+       {"", 0, ErrSyntax},
        {"0", 0, nil},
        {"1", 1, nil},
        {"12345", 12345, nil},
        {"012345", 12345, nil},
-       {"12345x", 0, os.EINVAL},
+       {"12345x", 0, ErrSyntax},
        {"987654321", 987654321, nil},
        {"4294967295", 1<<32 - 1, nil},
-       {"4294967296", 1<<32 - 1, os.ERANGE},
+       {"4294967296", 1<<32 - 1, ErrRange},
 }
 
 type atoi32Test struct {
@@ -126,7 +126,7 @@ type atoi32Test struct {
 }
 
 var atoi32tests = []atoi32Test{
-       {"", 0, os.EINVAL},
+       {"", 0, ErrSyntax},
        {"0", 0, nil},
        {"-0", 0, nil},
        {"1", 1, nil},
@@ -135,16 +135,16 @@ var atoi32tests = []atoi32Test{
        {"-12345", -12345, nil},
        {"012345", 12345, nil},
        {"-012345", -12345, nil},
-       {"12345x", 0, os.EINVAL},
-       {"-12345x", 0, os.EINVAL},
+       {"12345x", 0, ErrSyntax},
+       {"-12345x", 0, ErrSyntax},
        {"987654321", 987654321, nil},
        {"-987654321", -987654321, nil},
        {"2147483647", 1<<31 - 1, nil},
        {"-2147483647", -(1<<31 - 1), nil},
-       {"2147483648", 1<<31 - 1, os.ERANGE},
+       {"2147483648", 1<<31 - 1, ErrRange},
        {"-2147483648", -1 << 31, nil},
-       {"2147483649", 1<<31 - 1, os.ERANGE},
-       {"-2147483649", -1 << 31, os.ERANGE},
+       {"2147483649", 1<<31 - 1, ErrRange},
+       {"-2147483649", -1 << 31, ErrRange},
 }
 
 func init() {
index 3096957..991d3ac 100644 (file)
@@ -96,7 +96,7 @@ func myatof32(s string) (f float32, ok bool) {
 func TestFp(t *testing.T) {
        f, err := os.Open("testfp.txt")
        if err != nil {
-               t.Fatal("testfp: open testfp.txt:", err.String())
+               t.Fatal("testfp: open testfp.txt:", err)
        }
        defer f.Close()
 
index bbb9783..7efdcfe 100644 (file)
@@ -18,32 +18,32 @@ func quoteWith(s string, quote byte, ASCIIonly bool) string {
        var buf bytes.Buffer
        buf.WriteByte(quote)
        for width := 0; len(s) > 0; s = s[width:] {
-               rune := int(s[0])
+               r := rune(s[0])
                width = 1
-               if rune >= utf8.RuneSelf {
-                       rune, width = utf8.DecodeRuneInString(s)
+               if r >= utf8.RuneSelf {
+                       r, width = utf8.DecodeRuneInString(s)
                }
-               if width == 1 && rune == utf8.RuneError {
+               if width == 1 && r == utf8.RuneError {
                        buf.WriteString(`\x`)
                        buf.WriteByte(lowerhex[s[0]>>4])
                        buf.WriteByte(lowerhex[s[0]&0xF])
                        continue
                }
-               if rune == int(quote) || rune == '\\' { // always backslashed
+               if r == rune(quote) || r == '\\' { // always backslashed
                        buf.WriteByte('\\')
-                       buf.WriteByte(byte(rune))
+                       buf.WriteByte(byte(r))
                        continue
                }
                if ASCIIonly {
-                       if rune <= unicode.MaxASCII && unicode.IsPrint(rune) {
-                               buf.WriteRune(rune)
+                       if r <= unicode.MaxASCII && unicode.IsPrint(r) {
+                               buf.WriteRune(r)
                                continue
                        }
-               } else if unicode.IsPrint(rune) {
-                       buf.WriteRune(rune)
+               } else if unicode.IsPrint(r) {
+                       buf.WriteRune(r)
                        continue
                }
-               switch rune {
+               switch r {
                case '\a':
                        buf.WriteString(`\a`)
                case '\b':
@@ -60,22 +60,22 @@ func quoteWith(s string, quote byte, ASCIIonly bool) string {
                        buf.WriteString(`\v`)
                default:
                        switch {
-                       case rune < ' ':
+                       case r < ' ':
                                buf.WriteString(`\x`)
                                buf.WriteByte(lowerhex[s[0]>>4])
                                buf.WriteByte(lowerhex[s[0]&0xF])
-                       case rune > unicode.MaxRune:
-                               rune = 0xFFFD
+                       case r > unicode.MaxRune:
+                               r = 0xFFFD
                                fallthrough
-                       case rune < 0x10000:
+                       case r < 0x10000:
                                buf.WriteString(`\u`)
                                for s := 12; s >= 0; s -= 4 {
-                                       buf.WriteByte(lowerhex[rune>>uint(s)&0xF])
+                                       buf.WriteByte(lowerhex[r>>uint(s)&0xF])
                                }
                        default:
                                buf.WriteString(`\U`)
                                for s := 28; s >= 0; s -= 4 {
-                                       buf.WriteByte(lowerhex[rune>>uint(s)&0xF])
+                                       buf.WriteByte(lowerhex[r>>uint(s)&0xF])
                                }
                        }
                }
@@ -130,8 +130,8 @@ func CanBackquote(s string) bool {
        return true
 }
 
-func unhex(b byte) (v int, ok bool) {
-       c := int(b)
+func unhex(b byte) (v rune, ok bool) {
+       c := rune(b)
        switch {
        case '0' <= c && c <= '9':
                return c - '0', true
@@ -157,22 +157,22 @@ func unhex(b byte) (v int, ok bool) {
 // If set to a single quote, it permits the sequence \' and disallows unescaped '.
 // If set to a double quote, it permits \" and disallows unescaped ".
 // If set to zero, it does not permit either escape and allows both quote characters to appear unescaped.
-func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string, err os.Error) {
+func UnquoteChar(s string, quote byte) (value rune, multibyte bool, tail string, err os.Error) {
        // easy cases
        switch c := s[0]; {
        case c == quote && (quote == '\'' || quote == '"'):
-               err = os.EINVAL
+               err = ErrSyntax
                return
        case c >= utf8.RuneSelf:
                r, size := utf8.DecodeRuneInString(s)
                return r, true, s[size:], nil
        case c != '\\':
-               return int(s[0]), false, s[1:], nil
+               return rune(s[0]), false, s[1:], nil
        }
 
        // hard case: c is backslash
        if len(s) <= 1 {
-               err = os.EINVAL
+               err = ErrSyntax
                return
        }
        c := s[1]
@@ -203,15 +203,15 @@ func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string,
                case 'U':
                        n = 8
                }
-               v := 0
+               var v rune
                if len(s) < n {
-                       err = os.EINVAL
+                       err = ErrSyntax
                        return
                }
                for j := 0; j < n; j++ {
                        x, ok := unhex(s[j])
                        if !ok {
-                               err = os.EINVAL
+                               err = ErrSyntax
                                return
                        }
                        v = v<<4 | x
@@ -223,19 +223,19 @@ func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string,
                        break
                }
                if v > unicode.MaxRune {
-                       err = os.EINVAL
+                       err = ErrSyntax
                        return
                }
                value = v
                multibyte = true
        case '0', '1', '2', '3', '4', '5', '6', '7':
-               v := int(c) - '0'
+               v := rune(c) - '0'
                if len(s) < 2 {
-                       err = os.EINVAL
+                       err = ErrSyntax
                        return
                }
                for j := 0; j < 2; j++ { // one digit already; two more
-                       x := int(s[j]) - '0'
+                       x := rune(s[j]) - '0'
                        if x < 0 || x > 7 {
                                return
                        }
@@ -243,7 +243,7 @@ func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string,
                }
                s = s[2:]
                if v > 255 {
-                       err = os.EINVAL
+                       err = ErrSyntax
                        return
                }
                value = v
@@ -251,12 +251,12 @@ func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string,
                value = '\\'
        case '\'', '"':
                if c != quote {
-                       err = os.EINVAL
+                       err = ErrSyntax
                        return
                }
-               value = int(c)
+               value = rune(c)
        default:
-               err = os.EINVAL
+               err = ErrSyntax
                return
        }
        tail = s
@@ -271,29 +271,29 @@ func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string,
 func Unquote(s string) (t string, err os.Error) {
        n := len(s)
        if n < 2 {
-               return "", os.EINVAL
+               return "", ErrSyntax
        }
        quote := s[0]
        if quote != s[n-1] {
-               return "", os.EINVAL
+               return "", ErrSyntax
        }
        s = s[1 : n-1]
 
        if quote == '`' {
                if strings.Contains(s, "`") {
-                       return "", os.EINVAL
+                       return "", ErrSyntax
                }
                return s, nil
        }
        if quote != '"' && quote != '\'' {
-               return "", os.EINVAL
+               return "", ErrSyntax
        }
        if strings.Index(s, "\n") >= 0 {
-               return "", os.EINVAL
+               return "", ErrSyntax
        }
 
        // Is it trivial?  Avoid allocation.
-       if strings.Index(s, `\`) < 0 && strings.IndexRune(s, int(quote)) < 0 {
+       if strings.Index(s, `\`) < 0 && strings.IndexRune(s, rune(quote)) < 0 {
                switch quote {
                case '"':
                        return s, nil
@@ -319,7 +319,7 @@ func Unquote(s string) (t string, err os.Error) {
                }
                if quote == '\'' && len(s) != 0 {
                        // single-quoted must be single character
-                       return "", os.EINVAL
+                       return "", ErrSyntax
                }
        }
        return buf.String(), nil
index 0311f77..9a59770 100644 (file)
@@ -5,7 +5,6 @@
 package strconv_test
 
 import (
-       "os"
        . "strconv"
        "testing"
 )
@@ -210,8 +209,8 @@ func TestUnquote(t *testing.T) {
        }
 
        for _, s := range misquoted {
-               if out, err := Unquote(s); out != "" || err != os.EINVAL {
-                       t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", os.EINVAL)
+               if out, err := Unquote(s); out != "" || err != ErrSyntax {
+                       t.Errorf("Unquote(%#q) = %q, %v want %q, %v", s, out, err, "", ErrSyntax)
                }
        }
 }
index eb515de..f4385a4 100644 (file)
@@ -60,16 +60,16 @@ func (r *Reader) UnreadByte() 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 (r *Reader) ReadRune() (rune int, size int, err os.Error) {
+func (r *Reader) ReadRune() (ch rune, size int, err os.Error) {
        if r.i >= len(r.s) {
                return 0, 0, os.EOF
        }
        r.prevRune = r.i
        if c := r.s[r.i]; c < utf8.RuneSelf {
                r.i++
-               return int(c), 1, nil
+               return rune(c), 1, nil
        }
-       rune, size = utf8.DecodeRuneInString(r.s[r.i:])
+       ch, size = utf8.DecodeRuneInString(r.s[r.i:])
        r.i += size
        return
 }
index e337856..23c7e2e 100644 (file)
@@ -159,12 +159,12 @@ func BenchmarkByteByteReplaces(b *testing.B) {
 // BenchmarkByteByteMap compares byteByteImpl against Map.
 func BenchmarkByteByteMap(b *testing.B) {
        str := Repeat("a", 100) + Repeat("b", 100)
-       fn := func(r int) int {
+       fn := func(r rune) rune {
                switch r {
                case 'a':
-                       return int('A')
+                       return 'A'
                case 'b':
-                       return int('B')
+                       return 'B'
                }
                return r
        }
index 58301fe..4f6e8a6 100644 (file)
@@ -21,11 +21,12 @@ func explode(s string, n int) []string {
                n = l
        }
        a := make([]string, n)
-       var size, rune int
+       var size int
+       var ch rune
        i, cur := 0, 0
        for ; i+1 < n; i++ {
-               rune, size = utf8.DecodeRuneInString(s[cur:])
-               a[i] = string(rune)
+               ch, size = utf8.DecodeRuneInString(s[cur:])
+               a[i] = string(ch)
                cur += size
        }
        // add the rest, if there is any
@@ -117,11 +118,11 @@ func LastIndex(s, sep string) int {
 }
 
 // IndexRune returns the index of the first instance of the Unicode code point
-// rune, or -1 if rune is not present in s.
-func IndexRune(s string, rune int) int {
+// r, or -1 if rune is not present in s.
+func IndexRune(s string, r rune) int {
        switch {
-       case rune < 0x80:
-               b := byte(rune)
+       case r < 0x80:
+               b := byte(r)
                for i := 0; i < len(s); i++ {
                        if s[i] == b {
                                return i
@@ -129,7 +130,7 @@ func IndexRune(s string, rune int) int {
                }
        default:
                for i, c := range s {
-                       if c == rune {
+                       if c == r {
                                return i
                        }
                }
@@ -241,7 +242,7 @@ func Fields(s string) []string {
 // FieldsFunc splits the string s at each run of Unicode code points c satisfying f(c)
 // and returns an array of slices of s. If all code points in s satisfy f(c) or the
 // string is empty, an empty slice is returned.
-func FieldsFunc(s string, f func(int) bool) []string {
+func FieldsFunc(s string, f func(rune) bool) []string {
        // First count the fields.
        n := 0
        inField := false
@@ -310,7 +311,7 @@ func HasSuffix(s, suffix string) bool {
 // Map returns a copy of the string s with all its characters modified
 // according to the mapping function. If mapping returns a negative value, the character is
 // dropped from the string with no replacement.
-func Map(mapping func(rune int) int, s string) string {
+func Map(mapping func(rune) rune, s string) string {
        // In the worst case, the string 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.
@@ -321,18 +322,18 @@ func Map(mapping func(rune int) int, s string) string {
        var b []byte
 
        for i, c := range s {
-               rune := mapping(c)
+               r := mapping(c)
                if b == nil {
-                       if rune == c {
+                       if r == c {
                                continue
                        }
                        b = make([]byte, maxbytes)
                        nbytes = copy(b, s[:i])
                }
-               if rune >= 0 {
+               if r >= 0 {
                        wid := 1
-                       if rune >= utf8.RuneSelf {
-                               wid = utf8.RuneLen(rune)
+                       if r >= utf8.RuneSelf {
+                               wid = utf8.RuneLen(r)
                        }
                        if nbytes+wid > maxbytes {
                                // Grow the buffer.
@@ -341,7 +342,7 @@ func Map(mapping func(rune int) int, s string) string {
                                copy(nb, b[0:nbytes])
                                b = nb
                        }
-                       nbytes += utf8.EncodeRune(b[nbytes:maxbytes], rune)
+                       nbytes += utf8.EncodeRune(b[nbytes:maxbytes], r)
                }
        }
        if b == nil {
@@ -375,44 +376,44 @@ func ToTitle(s string) string { return Map(unicode.ToTitle, s) }
 // ToUpperSpecial returns a copy of the string s with all Unicode letters mapped to their
 // upper case, giving priority to the special casing rules.
 func ToUpperSpecial(_case unicode.SpecialCase, s string) string {
-       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 string s with all Unicode letters mapped to their
 // lower case, giving priority to the special casing rules.
 func ToLowerSpecial(_case unicode.SpecialCase, s string) string {
-       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 string s with all Unicode letters mapped to their
 // title case, giving priority to the special casing rules.
 func ToTitleSpecial(_case unicode.SpecialCase, s string) string {
-       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.
@@ -423,9 +424,9 @@ func Title(s string) string {
        // 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)
@@ -438,7 +439,7 @@ func Title(s string) string {
 
 // TrimLeftFunc returns a slice of the string s with all leading
 // Unicode code points c satisfying f(c) removed.
-func TrimLeftFunc(s string, f func(r int) bool) string {
+func TrimLeftFunc(s string, f func(rune) bool) string {
        i := indexFunc(s, f, false)
        if i == -1 {
                return ""
@@ -448,7 +449,7 @@ func TrimLeftFunc(s string, f func(r int) bool) string {
 
 // TrimRightFunc returns a slice of the string s with all trailing
 // Unicode code points c satisfying f(c) removed.
-func TrimRightFunc(s string, f func(r int) bool) string {
+func TrimRightFunc(s string, f func(rune) bool) string {
        i := lastIndexFunc(s, f, false)
        if i >= 0 && s[i] >= utf8.RuneSelf {
                _, wid := utf8.DecodeRuneInString(s[i:])
@@ -461,34 +462,34 @@ func TrimRightFunc(s string, f func(r int) bool) string {
 
 // TrimFunc returns a slice of the string s with all leading
 // and trailing Unicode code points c satisfying f(c) removed.
-func TrimFunc(s string, f func(r int) bool) string {
+func TrimFunc(s string, f func(rune) bool) string {
        return TrimRightFunc(TrimLeftFunc(s, f), f)
 }
 
 // IndexFunc returns the index into s of the first Unicode
 // code point satisfying f(c), or -1 if none do.
-func IndexFunc(s string, f func(r int) bool) int {
+func IndexFunc(s string, f func(rune) bool) int {
        return indexFunc(s, f, true)
 }
 
 // LastIndexFunc returns the index into s of the last
 // Unicode code point satisfying f(c), or -1 if none do.
-func LastIndexFunc(s string, f func(r int) bool) int {
+func LastIndexFunc(s string, f func(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 string, f func(r int) bool, truth bool) int {
+func indexFunc(s string, f func(rune) bool, truth bool) int {
        start := 0
        for start < len(s) {
                wid := 1
-               rune := int(s[start])
-               if rune >= utf8.RuneSelf {
-                       rune, wid = utf8.DecodeRuneInString(s[start:])
+               r := rune(s[start])
+               if r >= utf8.RuneSelf {
+                       r, wid = utf8.DecodeRuneInString(s[start:])
                }
-               if f(rune) == truth {
+               if f(r) == truth {
                        return start
                }
                start += wid
@@ -499,19 +500,19 @@ func indexFunc(s string, 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 string, f func(r int) bool, truth bool) int {
+func lastIndexFunc(s string, f func(rune) bool, truth bool) int {
        for i := len(s); i > 0; {
-               rune, size := utf8.DecodeLastRuneInString(s[0:i])
+               r, size := utf8.DecodeLastRuneInString(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 { return IndexRune(cutset, rune) != -1 }
+func makeCutsetFunc(cutset string) func(rune) bool {
+       return func(r rune) bool { return IndexRune(cutset, r) != -1 }
 }
 
 // Trim returns a slice of the string s with all leading and
@@ -589,15 +590,15 @@ func Replace(s, old, new string, n int) string {
 func EqualFold(s, t string) bool {
        for s != "" && t != "" {
                // Extract first rune from each string.
-               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.DecodeRuneInString(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.DecodeRuneInString(t)
                        tr, t = r, t[size:]
index 0859ddd..4132996 100644 (file)
@@ -122,7 +122,7 @@ func TestLastIndexAny(t *testing.T) { runIndexTests(t, LastIndexAny, "LastIndexA
 
 var indexRuneTests = []struct {
        s    string
-       rune int
+       rune rune
        out  int
 }{
        {"a A x", 'A', 2},
@@ -312,7 +312,7 @@ var FieldsFuncTests = []FieldsTest{
 }
 
 func TestFieldsFunc(t *testing.T) {
-       pred := func(c int) bool { return c == 'X' }
+       pred := func(c rune) bool { return c == 'X' }
        for _, tt := range FieldsFuncTests {
                a := FieldsFunc(tt.s, pred)
                if !eq(a, tt.a) {
@@ -374,31 +374,31 @@ var trimSpaceTests = []StringTest{
        {"x ☺ ", "x ☺"},
 }
 
-func tenRunes(rune int) string {
-       r := make([]int, 10)
+func tenRunes(ch rune) string {
+       r := make([]rune, 10)
        for i := range r {
-               r[i] = rune
+               r[i] = ch
        }
        return string(r)
 }
 
 // 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 {
+       step := rune(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) {
        // Run a couple of awful growth/shrinkage tests
        a := tenRunes('a')
        // 1.  Grow.  This triggers two reallocations in Map.
-       maxRune := func(rune int) int { return unicode.MaxRune }
+       maxRune := func(rune) rune { return unicode.MaxRune }
        m := Map(maxRune, a)
        expect := tenRunes(unicode.MaxRune)
        if m != expect {
@@ -406,7 +406,7 @@ func TestMap(t *testing.T) {
        }
 
        // 2. Shrink
-       minRune := func(rune int) int { return 'a' }
+       minRune := func(rune) rune { return 'a' }
        m = Map(minRune, tenRunes(unicode.MaxRune))
        expect = a
        if m != expect {
@@ -428,9 +428,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
        }
@@ -441,8 +441,8 @@ func TestMap(t *testing.T) {
        }
 
        // 6. Identity
-       identity := func(rune int) int {
-               return rune
+       identity := func(r rune) rune {
+               return r
        }
        orig := "Input string that we expect not to be copied."
        m = Map(identity, orig)
@@ -457,8 +457,8 @@ func TestToUpper(t *testing.T) { runStringTests(t, ToUpper, "ToUpper", upperTest
 func TestToLower(t *testing.T) { runStringTests(t, ToLower, "ToLower", lowerTests) }
 
 func BenchmarkMapNoChanges(b *testing.B) {
-       identity := func(rune int) int {
-               return rune
+       identity := func(r rune) rune {
+               return r
        }
        for i := 0; i < b.N; i++ {
                Map(identity, "Some string that won't be modified.")
@@ -536,7 +536,7 @@ func TestTrim(t *testing.T) {
 }
 
 type predicate struct {
-       f    func(r int) bool
+       f    func(rune) bool
        name string
 }
 
@@ -544,7 +544,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",
@@ -552,7 +552,7 @@ var isValidRune = predicate{
 
 func not(p predicate) predicate {
        return predicate{
-               func(r int) bool {
+               func(r rune) bool {
                        return !p.f(r)
                },
                "not " + p.name,
@@ -645,9 +645,9 @@ func TestCaseConsistency(t *testing.T) {
        if testing.Short() {
                numRunes = 1000
        }
-       a := make([]int, numRunes)
+       a := make([]rune, numRunes)
        for i := range a {
-               a[i] = i
+               a[i] = rune(i)
        }
        s := string(a)
        // convert the cases.
@@ -706,7 +706,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
        }
@@ -720,30 +720,30 @@ func runesEqual(a, b []int) bool {
 
 var RunesTests = []struct {
        in    string
-       out   []int
+       out   []rune
        lossy bool
 }{
-       {"", []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) {
        for _, tt := range RunesTests {
-               a := []int(tt.in)
+               a := []rune(tt.in)
                if !runesEqual(a, tt.out) {
-                       t.Errorf("[]int(%q) = %v; want %v", tt.in, a, tt.out)
+                       t.Errorf("[]rune(%q) = %v; want %v", tt.in, a, tt.out)
                        continue
                }
                if !tt.lossy {
                        // can only test reassembly if we didn't lose information
                        s := string(a)
                        if s != tt.in {
-                               t.Errorf("string([]int(%q)) = %x; want %x", tt.in, s, tt.in)
+                               t.Errorf("string([]rune(%q)) = %x; want %x", tt.in, s, tt.in)
                        }
                }
        }
index e7fad72..34c6633 100644 (file)
@@ -97,7 +97,7 @@ func (t *Template) Execute(wr io.Writer, data interface{}) (err os.Error) {
                line: 1,
                vars: []variable{{"$", value}},
        }
-       if t.Root == nil {
+       if t.Tree == nil || t.Root == nil {
                state.errorf("must be parsed before execution")
        }
        state.walk(value, t.Root)
index 50b0ad2..2d2b402 100644 (file)
@@ -98,7 +98,7 @@ var tVal = &T{
        Empty3:            []int{7, 8},
        Empty4:            &U{"UinEmpty"},
        NonEmptyInterface: new(T),
-       Str:               os.NewError("foozle"),
+       Str:               bytes.NewBuffer([]byte("foozle")),
        PI:                newInt(23),
        PSI:               newIntSlice(21, 22, 23),
        Tmpl:              Must(New("x").Parse("test template")), // "x" is the value of .X
@@ -644,7 +644,7 @@ func TestTree(t *testing.T) {
        if err != nil {
                t.Fatal("exec error:", err)
        }
-       stripSpace := func(r int) int {
+       stripSpace := func(r rune) rune {
                if r == '\t' || r == '\n' {
                        return -1
                }
index feb1fd8..938559e 100644 (file)
@@ -279,7 +279,7 @@ func JSEscape(w io.Writer, b []byte) {
        for i := 0; i < len(b); i++ {
                c := b[i]
 
-               if !jsIsSpecial(int(c)) {
+               if !jsIsSpecial(rune(c)) {
                        // fast path: nothing to do
                        continue
                }
@@ -307,12 +307,12 @@ func JSEscape(w io.Writer, b []byte) {
                        }
                } else {
                        // Unicode rune.
-                       rune, size := utf8.DecodeRune(b[i:])
-                       if unicode.IsPrint(rune) {
+                       r, size := utf8.DecodeRune(b[i:])
+                       if unicode.IsPrint(r) {
                                w.Write(b[i : i+size])
                        } else {
                                // TODO(dsymonds): Do this without fmt?
-                               fmt.Fprintf(w, "\\u%04X", rune)
+                               fmt.Fprintf(w, "\\u%04X", r)
                        }
                        i += size - 1
                }
@@ -332,12 +332,12 @@ func JSEscapeString(s string) string {
        return b.String()
 }
 
-func jsIsSpecial(rune int) bool {
-       switch rune {
+func jsIsSpecial(r rune) bool {
+       switch r {
        case '\\', '\'', '"', '<', '>':
                return true
        }
-       return rune < ' ' || utf8.RuneSelf <= rune
+       return r < ' ' || utf8.RuneSelf <= r
 }
 
 // JSEscaper returns the escaped JavaScript equivalent of the textual
index 16ff590..04c105d 100644 (file)
@@ -131,21 +131,21 @@ type lexer struct {
 }
 
 // next returns the next rune in the input.
-func (l *lexer) next() (rune int) {
+func (l *lexer) next() (r rune) {
        if l.pos >= len(l.input) {
                l.width = 0
                return eof
        }
-       rune, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
+       r, l.width = utf8.DecodeRuneInString(l.input[l.pos:])
        l.pos += l.width
-       return rune
+       return r
 }
 
 // peek returns but does not consume the next rune in the input.
-func (l *lexer) peek() int {
-       rune := l.next()
+func (l *lexer) peek() rune {
+       r := l.next()
        l.backup()
-       return rune
+       return r
 }
 
 // backup steps back one rune. Can only be called once per call of next.
@@ -468,7 +468,7 @@ Loop:
 }
 
 // isSpace reports whether r is a space character.
-func isSpace(r int) bool {
+func isSpace(r rune) bool {
        switch r {
        case ' ', '\t', '\n', '\r':
                return true
@@ -477,6 +477,6 @@ func isSpace(r int) bool {
 }
 
 // isAlphaNumeric reports whether r is an alphabetic, digit, or underscore.
-func isAlphaNumeric(r int) bool {
+func isAlphaNumeric(r rune) bool {
        return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r)
 }
index 756a60e..9ec1925 100644 (file)
@@ -123,9 +123,9 @@ func Value(t reflect.Type, rand *rand.Rand) (value reflect.Value, ok bool) {
                return s, true
        case reflect.String:
                numChars := rand.Intn(complexSize)
-               codePoints := make([]int, numChars)
+               codePoints := make([]rune, numChars)
                for i := 0; i < numChars; i++ {
-                       codePoints[i] = rand.Intn(0x10ffff)
+                       codePoints[i] = rune(rand.Intn(0x10ffff))
                }
                return reflect.ValueOf(string(codePoints)), true
        case reflect.Struct:
index 50e96a5..1a629c9 100644 (file)
@@ -45,12 +45,12 @@ const (
        UnixDate = "Mon Jan _2 15:04:05 MST 2006"
        RubyDate = "Mon Jan 02 15:04:05 -0700 2006"
        RFC822   = "02 Jan 06 1504 MST"
-       // RFC822 with Zulu time.
-       RFC822Z = "02 Jan 06 1504 -0700"
-       RFC850  = "Monday, 02-Jan-06 15:04:05 MST"
-       RFC1123 = "Mon, 02 Jan 2006 15:04:05 MST"
-       RFC3339 = "2006-01-02T15:04:05Z07:00"
-       Kitchen = "3:04PM"
+       RFC822Z  = "02 Jan 06 1504 -0700" // RFC822 with numeric zone
+       RFC850   = "Monday, 02-Jan-06 15:04:05 MST"
+       RFC1123  = "Mon, 02 Jan 2006 15:04:05 MST"
+       RFC1123Z = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
+       RFC3339  = "2006-01-02T15:04:05Z07:00"
+       Kitchen  = "3:04PM"
        // Handy time stamps.
        Stamp      = "Jan _2 15:04:05"
        StampMilli = "Jan _2 15:04:05.000"
index 353976c..e4cf513 100644 (file)
@@ -201,6 +201,7 @@ var formatTests = []FormatTest{
        {"RFC822", RFC822, "04 Feb 09 2100 PST"},
        {"RFC850", RFC850, "Wednesday, 04-Feb-09 21:00:57 PST"},
        {"RFC1123", RFC1123, "Wed, 04 Feb 2009 21:00:57 PST"},
+       {"RFC1123Z", RFC1123Z, "Wed, 04 Feb 2009 21:00:57 -0800"},
        {"RFC3339", RFC3339, "2009-02-04T21:00:57-08:00"},
        {"Kitchen", Kitchen, "9:00PM"},
        {"am/pm", "3pm", "9pm"},
@@ -240,6 +241,7 @@ var parseTests = []ParseTest{
        {"RubyDate", RubyDate, "Thu Feb 04 21:00:57 -0800 2010", true, true, 1, 0},
        {"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57 PST", true, true, 1, 0},
        {"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57 PST", true, true, 1, 0},
+       {"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57 -0800", true, true, 1, 0},
        {"RFC3339", RFC3339, "2010-02-04T21:00:57-08:00", true, false, 1, 0},
        {"custom: \"2006-01-02 15:04:05-07\"", "2006-01-02 15:04:05-07", "2010-02-04 21:00:57-08", true, false, 1, 0},
        // Optional fractional seconds.
@@ -248,6 +250,7 @@ var parseTests = []ParseTest{
        {"RubyDate", RubyDate, "Thu Feb 04 21:00:57.012 -0800 2010", true, true, 1, 3},
        {"RFC850", RFC850, "Thursday, 04-Feb-10 21:00:57.0123 PST", true, true, 1, 4},
        {"RFC1123", RFC1123, "Thu, 04 Feb 2010 21:00:57.01234 PST", true, true, 1, 5},
+       {"RFC1123Z", RFC1123Z, "Thu, 04 Feb 2010 21:00:57.01234 -0800", true, true, 1, 5},
        {"RFC3339", RFC3339, "2010-02-04T21:00:57.012345678-08:00", true, false, 1, 9},
        // Amount of white space should not matter.
        {"ANSIC", ANSIC, "Thu Feb 4 21:00:57 2010", false, true, 1, 0},
index 6793fd7..4800bd6 100644 (file)
@@ -5,9 +5,9 @@
 package unicode
 
 // IsDigit reports whether the rune is a decimal digit.
-func IsDigit(rune int) bool {
-       if rune <= MaxLatin1 {
-               return '0' <= rune && rune <= '9'
+func IsDigit(r rune) bool {
+       if r <= MaxLatin1 {
+               return '0' <= r && r <= '9'
        }
-       return Is(Digit, rune)
+       return Is(Digit, r)
 }
index ae3c0ec..551c42a 100644 (file)
@@ -9,7 +9,7 @@ import (
        . "unicode"
 )
 
-var testDigit = []int{
+var testDigit = []rune{
        0x0030,
        0x0039,
        0x0661,
@@ -68,7 +68,7 @@ var testDigit = []int{
        0x1D7CE,
 }
 
-var testLetter = []int{
+var testLetter = []rune{
        0x0041,
        0x0061,
        0x00AA,
@@ -118,7 +118,7 @@ func TestDigit(t *testing.T) {
 
 // Test that the special case in IsDigit agrees with the table
 func TestDigitOptimization(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                if Is(Digit, i) != IsDigit(i) {
                        t.Errorf("IsDigit(U+%04X) disagrees with Is(Digit)", i)
                }
index d482aac..9343bc9 100644 (file)
@@ -31,13 +31,13 @@ var PrintRanges = []*RangeTable{
 // IsGraphic reports whether the rune is defined as a Graphic by Unicode.
 // Such characters include letters, marks, numbers, punctuation, symbols, and
 // spaces, from categories L, M, N, P, S, Zs.
-func IsGraphic(rune int) bool {
+func IsGraphic(r rune) bool {
        // We cast to uint32 to avoid the extra test for negative,
        // and in the index we cast to uint8 to avoid the range check.
-       if uint32(rune) <= MaxLatin1 {
-               return properties[uint8(rune)]&pg != 0
+       if uint32(r) <= MaxLatin1 {
+               return properties[uint8(r)]&pg != 0
        }
-       return IsOneOf(GraphicRanges, rune)
+       return IsOneOf(GraphicRanges, r)
 }
 
 // IsPrint reports whether the rune is defined as printable by Go. Such
@@ -45,18 +45,18 @@ func IsGraphic(rune int) bool {
 // ASCII space character, from categories L, M, N, P, S and the ASCII space
 // character.  This categorization is the same as IsGraphic except that the
 // only spacing character is ASCII space, U+0020.
-func IsPrint(rune int) bool {
-       if uint32(rune) <= MaxLatin1 {
-               return properties[uint8(rune)]&pp != 0
+func IsPrint(r rune) bool {
+       if uint32(r) <= MaxLatin1 {
+               return properties[uint8(r)]&pp != 0
        }
-       return IsOneOf(PrintRanges, rune)
+       return IsOneOf(PrintRanges, r)
 }
 
 // IsOneOf reports whether the rune is a member of one of the ranges.
 // The rune is known to be above Latin-1.
-func IsOneOf(set []*RangeTable, rune int) bool {
+func IsOneOf(set []*RangeTable, r rune) bool {
        for _, inside := range set {
-               if Is(inside, rune) {
+               if Is(inside, r) {
                        return true
                }
        }
@@ -66,43 +66,43 @@ func IsOneOf(set []*RangeTable, rune int) bool {
 // IsControl reports whether the rune is a control character.
 // The C (Other) Unicode category includes more code points
 // such as surrogates; use Is(C, rune) to test for them.
-func IsControl(rune int) bool {
-       if uint32(rune) <= MaxLatin1 {
-               return properties[uint8(rune)]&pC != 0
+func IsControl(r rune) bool {
+       if uint32(r) <= MaxLatin1 {
+               return properties[uint8(r)]&pC != 0
        }
        // All control characters are < Latin1Max.
        return false
 }
 
 // IsLetter reports whether the rune is a letter (category L).
-func IsLetter(rune int) bool {
-       if uint32(rune) <= MaxLatin1 {
-               return properties[uint8(rune)]&(pLu|pLl) != 0
+func IsLetter(r rune) bool {
+       if uint32(r) <= MaxLatin1 {
+               return properties[uint8(r)]&(pLu|pLl) != 0
        }
-       return Is(Letter, rune)
+       return Is(Letter, r)
 }
 
 // IsMark reports whether the rune is a mark character (category M).
-func IsMark(rune int) bool {
+func IsMark(r rune) bool {
        // There are no mark characters in Latin-1.
-       return Is(Mark, rune)
+       return Is(Mark, r)
 }
 
 // IsNumber reports whether the rune is a number (category N).
-func IsNumber(rune int) bool {
-       if uint32(rune) <= MaxLatin1 {
-               return properties[uint8(rune)]&pN != 0
+func IsNumber(r rune) bool {
+       if uint32(r) <= MaxLatin1 {
+               return properties[uint8(r)]&pN != 0
        }
-       return Is(Number, rune)
+       return Is(Number, r)
 }
 
 // IsPunct reports whether the rune is a Unicode punctuation character
 // (category P).
-func IsPunct(rune int) bool {
-       if uint32(rune) <= MaxLatin1 {
-               return properties[uint8(rune)]&pP != 0
+func IsPunct(r rune) bool {
+       if uint32(r) <= MaxLatin1 {
+               return properties[uint8(r)]&pP != 0
        }
-       return Is(Punct, rune)
+       return Is(Punct, r)
 }
 
 // IsSpace reports whether the rune is a space character as defined
@@ -111,22 +111,22 @@ func IsPunct(rune int) bool {
 //     '\t', '\n', '\v', '\f', '\r', ' ', U+0085 (NEL), U+00A0 (NBSP).
 // Other definitions of spacing characters are set by category
 // Z and property Pattern_White_Space.
-func IsSpace(rune int) bool {
+func IsSpace(r rune) bool {
        // This property isn't the same as Z; special-case it.
-       if uint32(rune) <= MaxLatin1 {
-               switch rune {
+       if uint32(r) <= MaxLatin1 {
+               switch r {
                case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
                        return true
                }
                return false
        }
-       return Is(White_Space, rune)
+       return Is(White_Space, r)
 }
 
 // IsSymbol reports whether the rune is a symbolic character.
-func IsSymbol(rune int) bool {
-       if uint32(rune) <= MaxLatin1 {
-               return properties[uint8(rune)]&pS != 0
+func IsSymbol(r rune) bool {
+       if uint32(r) <= MaxLatin1 {
+               return properties[uint8(r)]&pS != 0
        }
-       return Is(Symbol, rune)
+       return Is(Symbol, r)
 }
index 77c679f..7b1f620 100644 (file)
@@ -13,7 +13,7 @@ import (
 // in the Latin-1 range through the property table.
 
 func TestIsControlLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsControl(i)
                want := false
                switch {
@@ -29,7 +29,7 @@ func TestIsControlLatin1(t *testing.T) {
 }
 
 func TestIsLetterLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsLetter(i)
                want := Is(Letter, i)
                if got != want {
@@ -39,7 +39,7 @@ func TestIsLetterLatin1(t *testing.T) {
 }
 
 func TestIsUpperLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsUpper(i)
                want := Is(Upper, i)
                if got != want {
@@ -49,7 +49,7 @@ func TestIsUpperLatin1(t *testing.T) {
 }
 
 func TestIsLowerLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsLower(i)
                want := Is(Lower, i)
                if got != want {
@@ -59,7 +59,7 @@ func TestIsLowerLatin1(t *testing.T) {
 }
 
 func TestNumberLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsNumber(i)
                want := Is(Number, i)
                if got != want {
@@ -69,7 +69,7 @@ func TestNumberLatin1(t *testing.T) {
 }
 
 func TestIsPrintLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsPrint(i)
                want := IsOneOf(PrintRanges, i)
                if i == ' ' {
@@ -82,7 +82,7 @@ func TestIsPrintLatin1(t *testing.T) {
 }
 
 func TestIsGraphicLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsGraphic(i)
                want := IsOneOf(GraphicRanges, i)
                if got != want {
@@ -92,7 +92,7 @@ func TestIsGraphicLatin1(t *testing.T) {
 }
 
 func TestIsPunctLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsPunct(i)
                want := Is(Punct, i)
                if got != want {
@@ -102,7 +102,7 @@ func TestIsPunctLatin1(t *testing.T) {
 }
 
 func TestIsSpaceLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsSpace(i)
                want := Is(White_Space, i)
                if got != want {
@@ -112,7 +112,7 @@ func TestIsSpaceLatin1(t *testing.T) {
 }
 
 func TestIsSymbolLatin1(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                got := IsSymbol(i)
                want := Is(Symbol, i)
                if got != want {
index 38a11c4..01c485b 100644 (file)
@@ -71,7 +71,7 @@ const (
        MaxCase
 )
 
-type d [MaxCase]int32 // to make the CaseRanges text shorter
+type d [MaxCase]rune // to make the CaseRanges text shorter
 
 // If the Delta field of a CaseRange is UpperLower or LowerUpper, it means
 // this CaseRange represents a sequence of the form (say)
@@ -81,17 +81,17 @@ const (
 )
 
 // is16 uses binary search to test whether rune is in the specified slice of 16-bit ranges.
-func is16(ranges []Range16, rune uint16) bool {
+func is16(ranges []Range16, r uint16) bool {
        // binary search over ranges
        lo := 0
        hi := len(ranges)
        for lo < hi {
                m := lo + (hi-lo)/2
-               r := ranges[m]
-               if r.Lo <= rune && rune <= r.Hi {
-                       return (rune-r.Lo)%r.Stride == 0
+               range_ := ranges[m]
+               if range_.Lo <= r && r <= range_.Hi {
+                       return (r-range_.Lo)%range_.Stride == 0
                }
-               if rune < r.Lo {
+               if r < range_.Lo {
                        hi = m
                } else {
                        lo = m + 1
@@ -101,17 +101,17 @@ func is16(ranges []Range16, rune uint16) bool {
 }
 
 // is32 uses binary search to test whether rune is in the specified slice of 32-bit ranges.
-func is32(ranges []Range32, rune uint32) bool {
+func is32(ranges []Range32, r uint32) bool {
        // binary search over ranges
        lo := 0
        hi := len(ranges)
        for lo < hi {
                m := lo + (hi-lo)/2
-               r := ranges[m]
-               if r.Lo <= rune && rune <= r.Hi {
-                       return (rune-r.Lo)%r.Stride == 0
+               range_ := ranges[m]
+               if range_.Lo <= r && r <= range_.Hi {
+                       return (r-range_.Lo)%range_.Stride == 0
                }
-               if rune < r.Lo {
+               if r < range_.Lo {
                        hi = m
                } else {
                        lo = m + 1
@@ -121,11 +121,11 @@ func is32(ranges []Range32, rune uint32) bool {
 }
 
 // Is tests whether rune is in the specified table of ranges.
-func Is(rangeTab *RangeTable, rune int) bool {
+func Is(rangeTab *RangeTable, r rune) bool {
        // common case: rune is ASCII or Latin-1.
-       if uint32(rune) <= MaxLatin1 {
+       if uint32(r) <= MaxLatin1 {
                // Only need to check R16, since R32 is always >= 1<<16.
-               r16 := uint16(rune)
+               r16 := uint16(r)
                for _, r := range rangeTab.R16 {
                        if r16 > r.Hi {
                                continue
@@ -138,44 +138,44 @@ func Is(rangeTab *RangeTable, rune int) bool {
                return false
        }
        r16 := rangeTab.R16
-       if len(r16) > 0 && rune <= int(r16[len(r16)-1].Hi) {
-               return is16(r16, uint16(rune))
+       if len(r16) > 0 && r <= rune(r16[len(r16)-1].Hi) {
+               return is16(r16, uint16(r))
        }
        r32 := rangeTab.R32
-       if len(r32) > 0 && rune >= int(r32[0].Lo) {
-               return is32(r32, uint32(rune))
+       if len(r32) > 0 && r >= rune(r32[0].Lo) {
+               return is32(r32, uint32(r))
        }
        return false
 }
 
 // IsUpper reports whether the rune is an upper case letter.
-func IsUpper(rune int) bool {
+func IsUpper(r rune) bool {
        // See comment in IsGraphic.
-       if uint32(rune) <= MaxLatin1 {
-               return properties[uint8(rune)]&pLu != 0
+       if uint32(r) <= MaxLatin1 {
+               return properties[uint8(r)]&pLu != 0
        }
-       return Is(Upper, rune)
+       return Is(Upper, r)
 }
 
 // IsLower reports whether the rune is a lower case letter.
-func IsLower(rune int) bool {
+func IsLower(r rune) bool {
        // See comment in IsGraphic.
-       if uint32(rune) <= MaxLatin1 {
-               return properties[uint8(rune)]&pLl != 0
+       if uint32(r) <= MaxLatin1 {
+               return properties[uint8(r)]&pLl != 0
        }
-       return Is(Lower, rune)
+       return Is(Lower, r)
 }
 
 // IsTitle reports whether the rune is a title case letter.
-func IsTitle(rune int) bool {
-       if rune <= MaxLatin1 {
+func IsTitle(r rune) bool {
+       if r <= MaxLatin1 {
                return false
        }
-       return Is(Title, rune)
+       return Is(Title, r)
 }
 
 // to maps the rune using the specified case mapping.
-func to(_case int, rune int, caseRange []CaseRange) int {
+func to(_case int, r rune, caseRange []CaseRange) rune {
        if _case < 0 || MaxCase <= _case {
                return ReplacementChar // as reasonable an error as any
        }
@@ -184,9 +184,9 @@ func to(_case int, rune int, caseRange []CaseRange) int {
        hi := len(caseRange)
        for lo < hi {
                m := lo + (hi-lo)/2
-               r := caseRange[m]
-               if int(r.Lo) <= rune && rune <= int(r.Hi) {
-                       delta := int(r.Delta[_case])
+               cr := caseRange[m]
+               if rune(cr.Lo) <= r && r <= rune(cr.Hi) {
+                       delta := rune(cr.Delta[_case])
                        if delta > MaxRune {
                                // In an Upper-Lower sequence, which always starts with
                                // an UpperCase letter, the real deltas always look like:
@@ -198,82 +198,82 @@ func to(_case int, rune int, caseRange []CaseRange) int {
                                // bit in the sequence offset.
                                // The constants UpperCase and TitleCase are even while LowerCase
                                // is odd so we take the low bit from _case.
-                               return int(r.Lo) + ((rune-int(r.Lo))&^1 | _case&1)
+                               return rune(cr.Lo) + ((r-rune(cr.Lo))&^1 | rune(_case&1))
                        }
-                       return rune + delta
+                       return r + delta
                }
-               if rune < int(r.Lo) {
+               if r < rune(cr.Lo) {
                        hi = m
                } else {
                        lo = m + 1
                }
        }
-       return rune
+       return r
 }
 
 // To maps the rune to the specified case: UpperCase, LowerCase, or TitleCase.
-func To(_case int, rune int) int {
-       return to(_case, rune, CaseRanges)
+func To(_case int, r rune) rune {
+       return to(_case, r, CaseRanges)
 }
 
 // ToUpper maps the rune to upper case.
-func ToUpper(rune int) int {
-       if rune <= MaxASCII {
-               if 'a' <= rune && rune <= 'z' {
-                       rune -= 'a' - 'A'
+func ToUpper(r rune) rune {
+       if r <= MaxASCII {
+               if 'a' <= r && r <= 'z' {
+                       r -= 'a' - 'A'
                }
-               return rune
+               return r
        }
-       return To(UpperCase, rune)
+       return To(UpperCase, r)
 }
 
 // ToLower maps the rune to lower case.
-func ToLower(rune int) int {
-       if rune <= MaxASCII {
-               if 'A' <= rune && rune <= 'Z' {
-                       rune += 'a' - 'A'
+func ToLower(r rune) rune {
+       if r <= MaxASCII {
+               if 'A' <= r && r <= 'Z' {
+                       r += 'a' - 'A'
                }
-               return rune
+               return r
        }
-       return To(LowerCase, rune)
+       return To(LowerCase, r)
 }
 
 // ToTitle maps the rune to title case.
-func ToTitle(rune int) int {
-       if rune <= MaxASCII {
-               if 'a' <= rune && rune <= 'z' { // title case is upper case for ASCII
-                       rune -= 'a' - 'A'
+func ToTitle(r rune) rune {
+       if r <= MaxASCII {
+               if 'a' <= r && r <= 'z' { // title case is upper case for ASCII
+                       r -= 'a' - 'A'
                }
-               return rune
+               return r
        }
-       return To(TitleCase, rune)
+       return To(TitleCase, r)
 }
 
 // ToUpper maps the rune to upper case giving priority to the special mapping.
-func (special SpecialCase) ToUpper(rune int) int {
-       r := to(UpperCase, rune, []CaseRange(special))
-       if r == rune {
-               r = ToUpper(rune)
+func (special SpecialCase) ToUpper(r rune) rune {
+       r1 := to(UpperCase, r, []CaseRange(special))
+       if r1 == r {
+               r1 = ToUpper(r)
        }
-       return r
+       return r1
 }
 
 // ToTitle maps the rune to title case giving priority to the special mapping.
-func (special SpecialCase) ToTitle(rune int) int {
-       r := to(TitleCase, rune, []CaseRange(special))
-       if r == rune {
-               r = ToTitle(rune)
+func (special SpecialCase) ToTitle(r rune) rune {
+       r1 := to(TitleCase, r, []CaseRange(special))
+       if r1 == r {
+               r1 = ToTitle(r)
        }
-       return r
+       return r1
 }
 
 // ToLower maps the rune to lower case giving priority to the special mapping.
-func (special SpecialCase) ToLower(rune int) int {
-       r := to(LowerCase, rune, []CaseRange(special))
-       if r == rune {
-               r = ToLower(rune)
+func (special SpecialCase) ToLower(r rune) rune {
+       r1 := to(LowerCase, r, []CaseRange(special))
+       if r1 == r {
+               r1 = ToLower(r)
        }
-       return r
+       return r1
 }
 
 // caseOrbit is defined in tables.go as []foldPair.  Right now all the
@@ -300,27 +300,27 @@ type foldPair struct {
 //
 //     SimpleFold('1') = '1'
 //
-func SimpleFold(rune int) int {
+func SimpleFold(r rune) rune {
        // Consult caseOrbit table for special cases.
        lo := 0
        hi := len(caseOrbit)
        for lo < hi {
                m := lo + (hi-lo)/2
-               if int(caseOrbit[m].From) < rune {
+               if rune(caseOrbit[m].From) < r {
                        lo = m + 1
                } else {
                        hi = m
                }
        }
-       if lo < len(caseOrbit) && int(caseOrbit[lo].From) == rune {
-               return int(caseOrbit[lo].To)
+       if lo < len(caseOrbit) && rune(caseOrbit[lo].From) == r {
+               return rune(caseOrbit[lo].To)
        }
 
        // No folding specified.  This is a one- or two-element
        // equivalence class containing rune and ToLower(rune)
        // and ToUpper(rune) if they are different from rune.
-       if l := ToLower(rune); l != rune {
+       if l := ToLower(r); l != r {
                return l
        }
-       return ToUpper(rune)
+       return ToUpper(r)
 }
index 8d2665a..2d80562 100644 (file)
@@ -9,7 +9,7 @@ import (
        . "unicode"
 )
 
-var upperTest = []int{
+var upperTest = []rune{
        0x41,
        0xc0,
        0xd8,
@@ -33,7 +33,7 @@ var upperTest = []int{
        0x1d7ca,
 }
 
-var notupperTest = []int{
+var notupperTest = []rune{
        0x40,
        0x5b,
        0x61,
@@ -46,7 +46,7 @@ var notupperTest = []int{
        0x10000,
 }
 
-var letterTest = []int{
+var letterTest = []rune{
        0x41,
        0x61,
        0xaa,
@@ -82,7 +82,7 @@ var letterTest = []int{
        0x2fa1d,
 }
 
-var notletterTest = []int{
+var notletterTest = []rune{
        0x20,
        0x35,
        0x375,
@@ -94,7 +94,7 @@ var notletterTest = []int{
 }
 
 // Contains all the special cased Latin-1 chars.
-var spaceTest = []int{
+var spaceTest = []rune{
        0x09,
        0x0a,
        0x0b,
@@ -108,7 +108,8 @@ var spaceTest = []int{
 }
 
 type caseT struct {
-       cas, in, out int
+       cas     int
+       in, out rune
 }
 
 var caseTest = []caseT{
@@ -327,7 +328,7 @@ func TestIsSpace(t *testing.T) {
 // Check that the optimizations for IsLetter etc. agree with the tables.
 // We only need to check the Latin-1 range.
 func TestLetterOptimizations(t *testing.T) {
-       for i := 0; i <= MaxLatin1; i++ {
+       for i := rune(0); i <= MaxLatin1; i++ {
                if Is(Letter, i) != IsLetter(i) {
                        t.Errorf("IsLetter(U+%04X) disagrees with Is(Letter)", i)
                }
@@ -356,8 +357,8 @@ func TestLetterOptimizations(t *testing.T) {
 }
 
 func TestTurkishCase(t *testing.T) {
-       lower := []int("abcçdefgğhıijklmnoöprsştuüvyz")
-       upper := []int("ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ")
+       lower := []rune("abcçdefgğhıijklmnoöprsştuüvyz")
+       upper := []rune("ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ")
        for i, l := range lower {
                u := upper[i]
                if TurkishCase.ToLower(l) != l {
@@ -416,13 +417,13 @@ var simpleFoldTests = []string{
 
 func TestSimpleFold(t *testing.T) {
        for _, tt := range simpleFoldTests {
-               cycle := []int(tt)
-               rune := cycle[len(cycle)-1]
+               cycle := []rune(tt)
+               r := cycle[len(cycle)-1]
                for _, out := range cycle {
-                       if r := SimpleFold(rune); r != out {
-                               t.Errorf("SimpleFold(%#U) = %#U, want %#U", rune, r, out)
+                       if r := SimpleFold(r); r != out {
+                               t.Errorf("SimpleFold(%#U) = %#U, want %#U", r, r, out)
                        }
-                       rune = out
+                       r = out
                }
        }
 }
index dfd636d..1c5b801 100644 (file)
@@ -10,7 +10,7 @@ import (
 )
 
 type T struct {
-       rune   int
+       rune   rune
        script string
 }
 
index 372e38a..2b2eb28 100644 (file)
@@ -20,16 +20,16 @@ const (
 
 // IsSurrogate returns true if the specified Unicode code point
 // can appear in a surrogate pair.
-func IsSurrogate(rune int) bool {
-       return surr1 <= rune && rune < surr3
+func IsSurrogate(r rune) bool {
+       return surr1 <= r && r < surr3
 }
 
 // DecodeRune returns the UTF-16 decoding of a surrogate pair.
 // If the pair is not a valid UTF-16 surrogate pair, DecodeRune returns
 // the Unicode replacement code point U+FFFD.
-func DecodeRune(r1, r2 int) int {
+func DecodeRune(r1, r2 rune) rune {
        if surr1 <= r1 && r1 < surr2 && surr2 <= r2 && r2 < surr3 {
-               return (int(r1)-surr1)<<10 | (int(r2) - surr2) + 0x10000
+               return (rune(r1)-surr1)<<10 | (rune(r2) - surr2) + 0x10000
        }
        return unicode.ReplacementChar
 }
@@ -37,16 +37,16 @@ func DecodeRune(r1, r2 int) int {
 // EncodeRune returns the UTF-16 surrogate pair r1, r2 for the given rune.
 // If the rune is not a valid Unicode code point or does not need encoding,
 // EncodeRune returns U+FFFD, U+FFFD.
-func EncodeRune(rune int) (r1, r2 int) {
-       if rune < surrSelf || rune > unicode.MaxRune || IsSurrogate(rune) {
+func EncodeRune(r rune) (r1, r2 rune) {
+       if r < surrSelf || r > unicode.MaxRune || IsSurrogate(r) {
                return unicode.ReplacementChar, unicode.ReplacementChar
        }
-       rune -= surrSelf
-       return surr1 + (rune>>10)&0x3ff, surr2 + rune&0x3ff
+       r -= surrSelf
+       return surr1 + (r>>10)&0x3ff, surr2 + r&0x3ff
 }
 
 // Encode returns the UTF-16 encoding of the Unicode code point sequence s.
-func Encode(s []int) []uint16 {
+func Encode(s []rune) []uint16 {
        n := len(s)
        for _, v := range s {
                if v >= surrSelf {
@@ -76,15 +76,15 @@ func Encode(s []int) []uint16 {
 
 // Decode returns the Unicode code point sequence represented
 // by the UTF-16 encoding s.
-func Decode(s []uint16) []int {
-       a := make([]int, len(s))
+func Decode(s []uint16) []rune {
+       a := make([]rune, len(s))
        n := 0
        for i := 0; i < len(s); i++ {
                switch r := s[i]; {
                case surr1 <= r && r < surr2 && i+1 < len(s) &&
                        surr2 <= s[i+1] && s[i+1] < surr3:
                        // valid surrogate sequence
-                       a[n] = DecodeRune(int(r), int(s[i+1]))
+                       a[n] = DecodeRune(rune(r), rune(s[i+1]))
                        i++
                        n++
                case surr1 <= r && r < surr3:
@@ -93,7 +93,7 @@ func Decode(s []uint16) []int {
                        n++
                default:
                        // normal rune
-                       a[n] = int(r)
+                       a[n] = rune(r)
                        n++
                }
        }
index 2b9fb3d..7ea290a 100644 (file)
@@ -5,7 +5,6 @@
 package utf16_test
 
 import (
-       "fmt"
        "reflect"
        "testing"
        "unicode"
@@ -13,15 +12,15 @@ import (
 )
 
 type encodeTest struct {
-       in  []int
+       in  []rune
        out []uint16
 }
 
 var encodeTests = []encodeTest{
-       {[]int{1, 2, 3, 4}, []uint16{1, 2, 3, 4}},
-       {[]int{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff},
+       {[]rune{1, 2, 3, 4}, []uint16{1, 2, 3, 4}},
+       {[]rune{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff},
                []uint16{0xffff, 0xd800, 0xdc00, 0xd800, 0xdc01, 0xd808, 0xdf45, 0xdbff, 0xdfff}},
-       {[]int{'a', 'b', 0xd7ff, 0xd800, 0xdfff, 0xe000, 0x110000, -1},
+       {[]rune{'a', 'b', 0xd7ff, 0xd800, 0xdfff, 0xe000, 0x110000, -1},
                []uint16{'a', 'b', 0xd7ff, 0xfffd, 0xfffd, 0xe000, 0xfffd, 0xfffd}},
 }
 
@@ -29,7 +28,7 @@ func TestEncode(t *testing.T) {
        for _, tt := range encodeTests {
                out := Encode(tt.in)
                if !reflect.DeepEqual(out, tt.out) {
-                       t.Errorf("Encode(%v) = %v; want %v", hex(tt.in), hex16(out), hex16(tt.out))
+                       t.Errorf("Encode(%x) = %x; want %x", tt.in, out, tt.out)
                }
        }
 }
@@ -53,7 +52,7 @@ func TestEncodeRune(t *testing.T) {
                                        t.Errorf("#%d: ran out of tt.out", i)
                                        break
                                }
-                               if r1 != int(tt.out[j]) || r2 != int(tt.out[j+1]) {
+                               if r1 != rune(tt.out[j]) || r2 != rune(tt.out[j+1]) {
                                        t.Errorf("EncodeRune(%#x) = %#x, %#x; want %#x, %#x", r, r1, r2, tt.out[j], tt.out[j+1])
                                }
                                j += 2
@@ -71,48 +70,22 @@ func TestEncodeRune(t *testing.T) {
 
 type decodeTest struct {
        in  []uint16
-       out []int
+       out []rune
 }
 
 var decodeTests = []decodeTest{
-       {[]uint16{1, 2, 3, 4}, []int{1, 2, 3, 4}},
+       {[]uint16{1, 2, 3, 4}, []rune{1, 2, 3, 4}},
        {[]uint16{0xffff, 0xd800, 0xdc00, 0xd800, 0xdc01, 0xd808, 0xdf45, 0xdbff, 0xdfff},
-               []int{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff}},
-       {[]uint16{0xd800, 'a'}, []int{0xfffd, 'a'}},
-       {[]uint16{0xdfff}, []int{0xfffd}},
+               []rune{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff}},
+       {[]uint16{0xd800, 'a'}, []rune{0xfffd, 'a'}},
+       {[]uint16{0xdfff}, []rune{0xfffd}},
 }
 
 func TestDecode(t *testing.T) {
        for _, tt := range decodeTests {
                out := Decode(tt.in)
                if !reflect.DeepEqual(out, tt.out) {
-                       t.Errorf("Decode(%v) = %v; want %v", hex16(tt.in), hex(out), hex(tt.out))
+                       t.Errorf("Decode(%x) = %x; want %x", tt.in, out, tt.out)
                }
        }
 }
-
-type hex []int
-
-func (h hex) Format(f fmt.State, c int) {
-       fmt.Fprint(f, "[")
-       for i, v := range h {
-               if i > 0 {
-                       fmt.Fprint(f, " ")
-               }
-               fmt.Fprintf(f, "%x", v)
-       }
-       fmt.Fprint(f, "]")
-}
-
-type hex16 []uint16
-
-func (h hex16) Format(f fmt.State, c int) {
-       fmt.Fprint(f, "[")
-       for i, v := range h {
-               if i > 0 {
-                       fmt.Fprint(f, " ")
-               }
-               fmt.Fprintf(f, "%x", v)
-       }
-       fmt.Fprint(f, "]")
-}
index 83b56b9..b333479 100644 (file)
@@ -101,10 +101,10 @@ func (s *String) Slice(i, j int) string {
 
 // At returns the rune with index i in the String.  The sequence of runes is the same
 // as iterating over the contents with a "for range" clause.
-func (s *String) At(i int) int {
+func (s *String) At(i int) rune {
        // ASCII is easy.  Let the compiler catch the indexing error if there is one.
        if i < s.nonASCII {
-               return int(s.str[i])
+               return rune(s.str[i])
        }
 
        // Now we do need to know the index is valid.
@@ -112,35 +112,35 @@ func (s *String) At(i int) int {
                panic(outOfRange)
        }
 
-       var rune int
+       var r rune
 
        // Five easy common cases: within 1 spot of bytePos/runePos, or the beginning, or the end.
        // With these cases, all scans from beginning or end work in O(1) time per rune.
        switch {
 
        case i == s.runePos-1: // backing up one rune
-               rune, s.width = DecodeLastRuneInString(s.str[0:s.bytePos])
+               r, s.width = DecodeLastRuneInString(s.str[0:s.bytePos])
                s.runePos = i
                s.bytePos -= s.width
-               return rune
+               return r
        case i == s.runePos+1: // moving ahead one rune
                s.runePos = i
                s.bytePos += s.width
                fallthrough
        case i == s.runePos:
-               rune, s.width = DecodeRuneInString(s.str[s.bytePos:])
-               return rune
+               r, s.width = DecodeRuneInString(s.str[s.bytePos:])
+               return r
        case i == 0: // start of string
-               rune, s.width = DecodeRuneInString(s.str)
+               r, s.width = DecodeRuneInString(s.str)
                s.runePos = 0
                s.bytePos = 0
-               return rune
+               return r
 
        case i == s.numRunes-1: // last rune in string
-               rune, s.width = DecodeLastRuneInString(s.str)
+               r, s.width = DecodeLastRuneInString(s.str)
                s.runePos = i
                s.bytePos = len(s.str) - s.width
-               return rune
+               return r
        }
 
        // We need to do a linear scan.  There are three places to start from:
@@ -173,7 +173,7 @@ func (s *String) At(i int) int {
        if forward {
                // TODO: Is it much faster to use a range loop for this scan?
                for {
-                       rune, s.width = DecodeRuneInString(s.str[s.bytePos:])
+                       r, s.width = DecodeRuneInString(s.str[s.bytePos:])
                        if s.runePos == i {
                                break
                        }
@@ -182,7 +182,7 @@ func (s *String) At(i int) int {
                }
        } else {
                for {
-                       rune, s.width = DecodeLastRuneInString(s.str[0:s.bytePos])
+                       r, s.width = DecodeLastRuneInString(s.str[0:s.bytePos])
                        s.runePos--
                        s.bytePos -= s.width
                        if s.runePos == i {
@@ -190,7 +190,7 @@ func (s *String) At(i int) int {
                        }
                }
        }
-       return rune
+       return r
 }
 
 // We want the panic in At(i) to satisfy os.Error, because that's what
index f376b62..920d2a0 100644 (file)
@@ -12,7 +12,7 @@ import (
 
 func TestScanForwards(t *testing.T) {
        for _, s := range testStrings {
-               runes := []int(s)
+               runes := []rune(s)
                str := NewString(s)
                if str.RuneCount() != len(runes) {
                        t.Errorf("%s: expected %d runes; got %d", s, len(runes), str.RuneCount())
@@ -29,7 +29,7 @@ func TestScanForwards(t *testing.T) {
 
 func TestScanBackwards(t *testing.T) {
        for _, s := range testStrings {
-               runes := []int(s)
+               runes := []rune(s)
                str := NewString(s)
                if str.RuneCount() != len(runes) {
                        t.Errorf("%s: expected %d runes; got %d", s, len(runes), str.RuneCount())
@@ -57,7 +57,7 @@ func TestRandomAccess(t *testing.T) {
                if len(s) == 0 {
                        continue
                }
-               runes := []int(s)
+               runes := []rune(s)
                str := NewString(s)
                if str.RuneCount() != len(runes) {
                        t.Errorf("%s: expected %d runes; got %d", s, len(runes), str.RuneCount())
@@ -79,7 +79,7 @@ func TestRandomSliceAccess(t *testing.T) {
                if len(s) == 0 || s[0] == '\x80' { // the bad-UTF-8 string fools this simple test
                        continue
                }
-               runes := []int(s)
+               runes := []rune(s)
                str := NewString(s)
                if str.RuneCount() != len(runes) {
                        t.Errorf("%s: expected %d runes; got %d", s, len(runes), str.RuneCount())
index 3cd919d..a5f9983 100644 (file)
@@ -34,7 +34,7 @@ const (
        rune4Max = 1<<21 - 1
 )
 
-func decodeRuneInternal(p []byte) (rune, size int, short bool) {
+func decodeRuneInternal(p []byte) (r rune, size int, short bool) {
        n := len(p)
        if n < 1 {
                return RuneError, 0, true
@@ -43,7 +43,7 @@ func decodeRuneInternal(p []byte) (rune, size int, short bool) {
 
        // 1-byte, 7-bit sequence?
        if c0 < tx {
-               return int(c0), 1, false
+               return rune(c0), 1, false
        }
 
        // unexpected continuation byte?
@@ -62,11 +62,11 @@ func decodeRuneInternal(p []byte) (rune, size int, short bool) {
 
        // 2-byte, 11-bit sequence?
        if c0 < t3 {
-               rune = int(c0&mask2)<<6 | int(c1&maskx)
-               if rune <= rune1Max {
+               r = rune(c0&mask2)<<6 | rune(c1&maskx)
+               if r <= rune1Max {
                        return RuneError, 1, false
                }
-               return rune, 2, false
+               return r, 2, false
        }
 
        // need second continuation byte
@@ -80,11 +80,11 @@ func decodeRuneInternal(p []byte) (rune, size int, short bool) {
 
        // 3-byte, 16-bit sequence?
        if c0 < t4 {
-               rune = int(c0&mask3)<<12 | int(c1&maskx)<<6 | int(c2&maskx)
-               if rune <= rune2Max {
+               r = rune(c0&mask3)<<12 | rune(c1&maskx)<<6 | rune(c2&maskx)
+               if r <= rune2Max {
                        return RuneError, 1, false
                }
-               return rune, 3, false
+               return r, 3, false
        }
 
        // need third continuation byte
@@ -98,18 +98,18 @@ func decodeRuneInternal(p []byte) (rune, size int, short bool) {
 
        // 4-byte, 21-bit sequence?
        if c0 < t5 {
-               rune = int(c0&mask4)<<18 | int(c1&maskx)<<12 | int(c2&maskx)<<6 | int(c3&maskx)
-               if rune <= rune3Max {
+               r = rune(c0&mask4)<<18 | rune(c1&maskx)<<12 | rune(c2&maskx)<<6 | rune(c3&maskx)
+               if r <= rune3Max {
                        return RuneError, 1, false
                }
-               return rune, 4, false
+               return r, 4, false
        }
 
        // error
        return RuneError, 1, false
 }
 
-func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
+func decodeRuneInStringInternal(s string) (r rune, size int, short bool) {
        n := len(s)
        if n < 1 {
                return RuneError, 0, true
@@ -118,7 +118,7 @@ func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
 
        // 1-byte, 7-bit sequence?
        if c0 < tx {
-               return int(c0), 1, false
+               return rune(c0), 1, false
        }
 
        // unexpected continuation byte?
@@ -137,11 +137,11 @@ func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
 
        // 2-byte, 11-bit sequence?
        if c0 < t3 {
-               rune = int(c0&mask2)<<6 | int(c1&maskx)
-               if rune <= rune1Max {
+               r = rune(c0&mask2)<<6 | rune(c1&maskx)
+               if r <= rune1Max {
                        return RuneError, 1, false
                }
-               return rune, 2, false
+               return r, 2, false
        }
 
        // need second continuation byte
@@ -155,11 +155,11 @@ func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
 
        // 3-byte, 16-bit sequence?
        if c0 < t4 {
-               rune = int(c0&mask3)<<12 | int(c1&maskx)<<6 | int(c2&maskx)
-               if rune <= rune2Max {
+               r = rune(c0&mask3)<<12 | rune(c1&maskx)<<6 | rune(c2&maskx)
+               if r <= rune2Max {
                        return RuneError, 1, false
                }
-               return rune, 3, false
+               return r, 3, false
        }
 
        // need third continuation byte
@@ -173,11 +173,11 @@ func decodeRuneInStringInternal(s string) (rune, size int, short bool) {
 
        // 4-byte, 21-bit sequence?
        if c0 < t5 {
-               rune = int(c0&mask4)<<18 | int(c1&maskx)<<12 | int(c2&maskx)<<6 | int(c3&maskx)
-               if rune <= rune3Max {
+               r = rune(c0&mask4)<<18 | rune(c1&maskx)<<12 | rune(c2&maskx)<<6 | rune(c3&maskx)
+               if r <= rune3Max {
                        return RuneError, 1, false
                }
-               return rune, 4, false
+               return r, 4, false
        }
 
        // error
@@ -198,28 +198,28 @@ func FullRuneInString(s string) bool {
 }
 
 // DecodeRune unpacks the first UTF-8 encoding in p and returns the rune and its width in bytes.
-func DecodeRune(p []byte) (rune, size int) {
-       rune, size, _ = decodeRuneInternal(p)
+func DecodeRune(p []byte) (r rune, size int) {
+       r, size, _ = decodeRuneInternal(p)
        return
 }
 
 // DecodeRuneInString is like DecodeRune but its input is a string.
-func DecodeRuneInString(s string) (rune, size int) {
-       rune, size, _ = decodeRuneInStringInternal(s)
+func DecodeRuneInString(s string) (r rune, size int) {
+       r, size, _ = decodeRuneInStringInternal(s)
        return
 }
 
 // DecodeLastRune unpacks the last UTF-8 encoding in p
 // and returns the rune and its width in bytes.
-func DecodeLastRune(p []byte) (rune, size int) {
+func DecodeLastRune(p []byte) (r rune, size int) {
        end := len(p)
        if end == 0 {
                return RuneError, 0
        }
        start := end - 1
-       rune = int(p[start])
-       if rune < RuneSelf {
-               return rune, 1
+       r = rune(p[start])
+       if r < RuneSelf {
+               return r, 1
        }
        // guard against O(n^2) behavior when traversing
        // backwards through strings with long sequences of
@@ -236,23 +236,23 @@ func DecodeLastRune(p []byte) (rune, size int) {
        if start < 0 {
                start = 0
        }
-       rune, size = DecodeRune(p[start:end])
+       r, size = DecodeRune(p[start:end])
        if start+size != end {
                return RuneError, 1
        }
-       return rune, size
+       return r, size
 }
 
 // DecodeLastRuneInString is like DecodeLastRune but its input is a string.
-func DecodeLastRuneInString(s string) (rune, size int) {
+func DecodeLastRuneInString(s string) (r rune, size int) {
        end := len(s)
        if end == 0 {
                return RuneError, 0
        }
        start := end - 1
-       rune = int(s[start])
-       if rune < RuneSelf {
-               return rune, 1
+       r = rune(s[start])
+       if r < RuneSelf {
+               return r, 1
        }
        // guard against O(n^2) behavior when traversing
        // backwards through strings with long sequences of
@@ -269,23 +269,23 @@ func DecodeLastRuneInString(s string) (rune, size int) {
        if start < 0 {
                start = 0
        }
-       rune, size = DecodeRuneInString(s[start:end])
+       r, size = DecodeRuneInString(s[start:end])
        if start+size != end {
                return RuneError, 1
        }
-       return rune, size
+       return r, size
 }
 
 // RuneLen returns the number of bytes required to encode the rune.
-func RuneLen(rune int) int {
+func RuneLen(r rune) int {
        switch {
-       case rune <= rune1Max:
+       case r <= rune1Max:
                return 1
-       case rune <= rune2Max:
+       case r <= rune2Max:
                return 2
-       case rune <= rune3Max:
+       case r <= rune3Max:
                return 3
-       case rune <= rune4Max:
+       case r <= rune4Max:
                return 4
        }
        return -1
@@ -293,26 +293,24 @@ func RuneLen(rune int) int {
 
 // EncodeRune writes into p (which must be large enough) the UTF-8 encoding of the rune.
 // It returns the number of bytes written.
-func EncodeRune(p []byte, rune int) int {
+func EncodeRune(p []byte, r rune) int {
        // Negative values are erroneous.  Making it unsigned addresses the problem.
-       r := uint(rune)
-
-       if r <= rune1Max {
+       if uint32(r) <= rune1Max {
                p[0] = byte(r)
                return 1
        }
 
-       if r <= rune2Max {
+       if uint32(r) <= rune2Max {
                p[0] = t2 | byte(r>>6)
                p[1] = tx | byte(r)&maskx
                return 2
        }
 
-       if r > unicode.MaxRune {
+       if uint32(r) > unicode.MaxRune {
                r = RuneError
        }
 
-       if r <= rune3Max {
+       if uint32(r) <= rune3Max {
                p[0] = t3 | byte(r>>12)
                p[1] = tx | byte(r>>6)&maskx
                p[2] = tx | byte(r)&maskx
index 6cbbebc..857bcf6 100644 (file)
@@ -11,8 +11,8 @@ import (
 )
 
 type Utf8Map struct {
-       rune int
-       str  string
+       r   rune
+       str string
 }
 
 var utf8map = []Utf8Map{
@@ -58,11 +58,11 @@ func TestFullRune(t *testing.T) {
                m := utf8map[i]
                b := []byte(m.str)
                if !FullRune(b) {
-                       t.Errorf("FullRune(%q) (%U) = false, want true", b, m.rune)
+                       t.Errorf("FullRune(%q) (%U) = false, want true", b, m.r)
                }
                s := m.str
                if !FullRuneInString(s) {
-                       t.Errorf("FullRuneInString(%q) (%U) = false, want true", s, m.rune)
+                       t.Errorf("FullRuneInString(%q) (%U) = false, want true", s, m.r)
                }
                b1 := b[0 : len(b)-1]
                if FullRune(b1) {
@@ -80,10 +80,10 @@ func TestEncodeRune(t *testing.T) {
                m := utf8map[i]
                b := []byte(m.str)
                var buf [10]byte
-               n := EncodeRune(buf[0:], m.rune)
+               n := EncodeRune(buf[0:], m.r)
                b1 := buf[0:n]
                if !bytes.Equal(b, b1) {
-                       t.Errorf("EncodeRune(%#04x) = %q want %q", m.rune, b1, b)
+                       t.Errorf("EncodeRune(%#04x) = %q want %q", m.r, b1, b)
                }
        }
 }
@@ -92,25 +92,25 @@ func TestDecodeRune(t *testing.T) {
        for i := 0; i < len(utf8map); i++ {
                m := utf8map[i]
                b := []byte(m.str)
-               rune, size := DecodeRune(b)
-               if rune != m.rune || size != len(b) {
-                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b, rune, size, m.rune, len(b))
+               r, size := DecodeRune(b)
+               if r != m.r || size != len(b) {
+                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b, r, size, m.r, len(b))
                }
                s := m.str
-               rune, size = DecodeRuneInString(s)
-               if rune != m.rune || size != len(b) {
-                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", s, rune, size, m.rune, len(b))
+               r, size = DecodeRuneInString(s)
+               if r != m.r || size != len(b) {
+                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", s, r, size, m.r, len(b))
                }
 
                // there's an extra byte that bytes left behind - make sure trailing byte works
-               rune, size = DecodeRune(b[0:cap(b)])
-               if rune != m.rune || size != len(b) {
-                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b, rune, size, m.rune, len(b))
+               r, size = DecodeRune(b[0:cap(b)])
+               if r != m.r || size != len(b) {
+                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b, r, size, m.r, len(b))
                }
                s = m.str + "\x00"
-               rune, size = DecodeRuneInString(s)
-               if rune != m.rune || size != len(b) {
-                       t.Errorf("DecodeRuneInString(%q) = %#04x, %d want %#04x, %d", s, rune, size, m.rune, len(b))
+               r, size = DecodeRuneInString(s)
+               if r != m.r || size != len(b) {
+                       t.Errorf("DecodeRuneInString(%q) = %#04x, %d want %#04x, %d", s, r, size, m.r, len(b))
                }
 
                // make sure missing bytes fail
@@ -118,14 +118,14 @@ func TestDecodeRune(t *testing.T) {
                if wantsize >= len(b) {
                        wantsize = 0
                }
-               rune, size = DecodeRune(b[0 : len(b)-1])
-               if rune != RuneError || size != wantsize {
-                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b[0:len(b)-1], rune, size, RuneError, wantsize)
+               r, size = DecodeRune(b[0 : len(b)-1])
+               if r != RuneError || size != wantsize {
+                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b[0:len(b)-1], r, size, RuneError, wantsize)
                }
                s = m.str[0 : len(m.str)-1]
-               rune, size = DecodeRuneInString(s)
-               if rune != RuneError || size != wantsize {
-                       t.Errorf("DecodeRuneInString(%q) = %#04x, %d want %#04x, %d", s, rune, size, RuneError, wantsize)
+               r, size = DecodeRuneInString(s)
+               if r != RuneError || size != wantsize {
+                       t.Errorf("DecodeRuneInString(%q) = %#04x, %d want %#04x, %d", s, r, size, RuneError, wantsize)
                }
 
                // make sure bad sequences fail
@@ -134,14 +134,14 @@ func TestDecodeRune(t *testing.T) {
                } else {
                        b[len(b)-1] = 0x7F
                }
-               rune, size = DecodeRune(b)
-               if rune != RuneError || size != 1 {
-                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b, rune, size, RuneError, 1)
+               r, size = DecodeRune(b)
+               if r != RuneError || size != 1 {
+                       t.Errorf("DecodeRune(%q) = %#04x, %d want %#04x, %d", b, r, size, RuneError, 1)
                }
                s = string(b)
-               rune, size = DecodeRune(b)
-               if rune != RuneError || size != 1 {
-                       t.Errorf("DecodeRuneInString(%q) = %#04x, %d want %#04x, %d", s, rune, size, RuneError, 1)
+               r, size = DecodeRune(b)
+               if r != RuneError || size != 1 {
+                       t.Errorf("DecodeRuneInString(%q) = %#04x, %d want %#04x, %d", s, r, size, RuneError, 1)
                }
 
        }
@@ -164,7 +164,7 @@ func TestSequencing(t *testing.T) {
 // it's good to verify
 func TestIntConversion(t *testing.T) {
        for _, ts := range testStrings {
-               runes := []int(ts)
+               runes := []rune(ts)
                if RuneCountInString(ts) != len(runes) {
                        t.Errorf("%q: expected %d runes; got %d", ts, len(runes), RuneCountInString(ts))
                        break
@@ -182,7 +182,7 @@ func TestIntConversion(t *testing.T) {
 func testSequence(t *testing.T, s string) {
        type info struct {
                index int
-               rune  int
+               r     rune
        }
        index := make([]info, len(s))
        b := []byte(s)
@@ -195,14 +195,14 @@ func testSequence(t *testing.T, s string) {
                }
                index[j] = info{i, r}
                j++
-               rune1, size1 := DecodeRune(b[i:])
-               if r != rune1 {
-                       t.Errorf("DecodeRune(%q) = %#04x, want %#04x", s[i:], rune1, r)
+               r1, size1 := DecodeRune(b[i:])
+               if r != r1 {
+                       t.Errorf("DecodeRune(%q) = %#04x, want %#04x", s[i:], r1, r)
                        return
                }
-               rune2, size2 := DecodeRuneInString(s[i:])
-               if r != rune2 {
-                       t.Errorf("DecodeRuneInString(%q) = %#04x, want %#04x", s[i:], rune2, r)
+               r2, size2 := DecodeRuneInString(s[i:])
+               if r != r2 {
+                       t.Errorf("DecodeRuneInString(%q) = %#04x, want %#04x", s[i:], r2, r)
                        return
                }
                if size1 != size2 {
@@ -213,18 +213,18 @@ func testSequence(t *testing.T, s string) {
        }
        j--
        for si = len(s); si > 0; {
-               rune1, size1 := DecodeLastRune(b[0:si])
-               rune2, size2 := DecodeLastRuneInString(s[0:si])
+               r1, size1 := DecodeLastRune(b[0:si])
+               r2, size2 := DecodeLastRuneInString(s[0:si])
                if size1 != size2 {
                        t.Errorf("DecodeLastRune/DecodeLastRuneInString(%q, %d) size mismatch %d/%d", s, si, size1, size2)
                        return
                }
-               if rune1 != index[j].rune {
-                       t.Errorf("DecodeLastRune(%q, %d) = %#04x, want %#04x", s, si, rune1, index[j].rune)
+               if r1 != index[j].r {
+                       t.Errorf("DecodeLastRune(%q, %d) = %#04x, want %#04x", s, si, r1, index[j].r)
                        return
                }
-               if rune2 != index[j].rune {
-                       t.Errorf("DecodeLastRuneInString(%q, %d) = %#04x, want %#04x", s, si, rune2, index[j].rune)
+               if r2 != index[j].r {
+                       t.Errorf("DecodeLastRuneInString(%q, %d) = %#04x, want %#04x", s, si, r2, index[j].r)
                        return
                }
                si -= size1
index ad3aa97..eb358d5 100644 (file)
@@ -8,10 +8,10 @@ import (
        "reflect"
        "testing"
 
-       "os"
        "bytes"
-       "strings"
+       "os"
        "strconv"
+       "strings"
 )
 
 type DriveType int
@@ -314,27 +314,27 @@ func TestMarshal(t *testing.T) {
 }
 
 var marshalErrorTests = []struct {
-       Value      interface{}
-       ExpectErr  string
-       ExpectKind reflect.Kind
+       Value interface{}
+       Err   string
+       Kind  reflect.Kind
 }{
        {
-               Value:      make(chan bool),
-               ExpectErr:  "xml: unsupported type: chan bool",
-               ExpectKind: reflect.Chan,
+               Value: make(chan bool),
+               Err:   "xml: unsupported type: chan bool",
+               Kind:  reflect.Chan,
        },
        {
                Value: map[string]string{
                        "question": "What do you get when you multiply six by nine?",
                        "answer":   "42",
                },
-               ExpectErr:  "xml: unsupported type: map[string] string",
-               ExpectKind: reflect.Map,
+               Err:  "xml: unsupported type: map[string] string",
+               Kind: reflect.Map,
        },
        {
-               Value:      map[*Ship]bool{nil: false},
-               ExpectErr:  "xml: unsupported type: map[*xml.Ship] bool",
-               ExpectKind: reflect.Map,
+               Value: map[*Ship]bool{nil: false},
+               Err:   "xml: unsupported type: map[*xml.Ship] bool",
+               Kind:  reflect.Map,
        },
 }
 
@@ -342,14 +342,11 @@ func TestMarshalErrors(t *testing.T) {
        for idx, test := range marshalErrorTests {
                buf := bytes.NewBuffer(nil)
                err := Marshal(buf, test.Value)
-               if got, want := err, test.ExpectErr; got == nil {
-                       t.Errorf("#%d: want error %s", idx, want)
-                       continue
-               } else if got.String() != want {
-                       t.Errorf("#%d: marshal(%#v) = [error] %q, want %q", idx, test.Value, got, want)
+               if err == nil || err.String() != test.Err {
+                       t.Errorf("#%d: marshal(%#v) = [error] %q, want %q", idx, test.Value, err, test.Err)
                }
-               if got, want := err.(*UnsupportedTypeError).Type.Kind(), test.ExpectKind; got != want {
-                       t.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx, test.Value, got, want)
+               if kind := err.(*UnsupportedTypeError).Type.Kind(); kind != test.Kind {
+                       t.Errorf("#%d: marshal(%#v) = [error kind] %s, want %s", idx, test.Value, kind, test.Kind)
                }
        }
 }
index f64e130..1fe20ac 100644 (file)
@@ -206,7 +206,7 @@ func fieldName(original string) string {
        }
 
        return strings.Map(
-               func(x int) int {
+               func(x rune) rune {
                        if x == '_' || unicode.IsDigit(x) || unicode.IsLetter(x) {
                                return unicode.ToLower(x)
                        }
index 85c24bc..bc03c8e 100644 (file)
@@ -960,13 +960,13 @@ Input:
 // Decide whether the given rune is in the XML Character Range, per
 // the Char production of http://www.xml.com/axml/testaxml.htm,
 // Section 2.2 Characters.
-func isInCharacterRange(rune int) (inrange bool) {
-       return rune == 0x09 ||
-               rune == 0x0A ||
-               rune == 0x0D ||
-               rune >= 0x20 && rune <= 0xDF77 ||
-               rune >= 0xE000 && rune <= 0xFFFD ||
-               rune >= 0x10000 && rune <= 0x10FFFF
+func isInCharacterRange(r rune) (inrange bool) {
+       return r == 0x09 ||
+               r == 0x0A ||
+               r == 0x0D ||
+               r >= 0x20 && r <= 0xDF77 ||
+               r >= 0xE000 && r <= 0xFFFD ||
+               r >= 0x10000 && r <= 0x10FFFF
 }
 
 // Get name space name: name with a : stuck in the middle.
@@ -1690,7 +1690,7 @@ func procInstEncoding(s string) string {
        if v[0] != '\'' && v[0] != '"' {
                return ""
        }
-       idx = strings.IndexRune(v[1:], int(v[0]))
+       idx = strings.IndexRune(v[1:], rune(v[0]))
        if idx == -1 {
                return ""
        }
index 8047eae..45467ed 100644 (file)
 
 extern char **environ;
 
-/* These functions are created for the main package.  */
-extern void __go_init_main (void);
-extern void real_main (void) asm ("main.main");
-
+extern void runtime_main (void);
 static void mainstart (void *);
 
 /* The main function.  */
@@ -47,13 +44,6 @@ main (int argc, char **argv)
   runtime_args (argc, (byte **) argv);
   runtime_osinit ();
   runtime_schedinit ();
-
-#if defined(HAVE_SRANDOM)
-  srandom ((unsigned int) time (NULL));
-#else
-  srand ((unsigned int) time (NULL));
-#endif
-
   __go_go (mainstart, NULL);
   runtime_mstart (runtime_m ());
   abort ();
@@ -62,13 +52,5 @@ main (int argc, char **argv)
 static void
 mainstart (void *arg __attribute__ ((unused)))
 {
-  __go_init_main ();
-
-  mstats.enablegc = 1;
-
-  real_main ();
-
-  runtime_exit (0);
-
-  abort ();
+  runtime_main ();
 }
index b243de2..e5c01f5 100644 (file)
@@ -128,6 +128,9 @@ struct Sched {
        volatile uint32 atomic; // atomic scheduling word (see below)
 
        int32 profilehz;        // cpu profiling rate
+       
+       bool init;  // running initialization
+       bool lockmain;  // init called runtime.LockOSThread
 
        Note    stopped;        // one g can set waitstop and wait here for m's to stop
 };
@@ -292,11 +295,7 @@ runtime_mcall(void (*pfn)(G*))
 //     make & queue new G
 //     call runtime_mstart
 //
-// The new G does:
-//
-//     call main_init_function
-//     call initdone
-//     call main_main
+// The new G calls runtime_main.
 void
 runtime_schedinit(void)
 {
@@ -340,6 +339,37 @@ runtime_schedinit(void)
        m->nomemprof--;
 }
 
+extern void main_init(void) __asm__ ("__go_init_main");
+extern void main_main(void) __asm__ ("main.main");
+
+// The main goroutine.
+void
+runtime_main(void)
+{
+       // Lock the main goroutine onto this, the main OS thread,
+       // during initialization.  Most programs won't care, but a few
+       // do require certain calls to be made by the main thread.
+       // Those can arrange for main.main to run in the main thread
+       // by calling runtime.LockOSThread during initialization
+       // to preserve the lock.
+       runtime_LockOSThread();
+       runtime_sched.init = true;
+       main_init();
+       runtime_sched.init = false;
+       if(!runtime_sched.lockmain)
+               runtime_UnlockOSThread();
+
+       // For gccgo we have to wait until after main is initialized
+       // to enable GC, because initializing main registers the GC
+       // roots.
+       mstats.enablegc = 1;
+
+       main_main();
+       runtime_exit(0);
+       for(;;)
+               *(int32*)0 = 0;
+}
+
 // Lock the scheduler.
 static void
 schedlock(void)
@@ -1233,16 +1263,6 @@ runtime_Gosched(void)
        runtime_gosched();
 }
 
-void runtime_LockOSThread (void)
-  __asm__ ("libgo_runtime.runtime.LockOSThread");
-
-void
-runtime_LockOSThread(void)
-{
-       m->lockedg = g;
-       g->lockedm = m;
-}
-
 // delete when scheduler is stronger
 int32
 runtime_gomaxprocsfunc(int32 n)
@@ -1282,12 +1302,24 @@ runtime_gomaxprocsfunc(int32 n)
        return ret;
 }
 
-void runtime_UnlockOSThread (void)
-  __asm__ ("libgo_runtime.runtime.UnlockOSThread");
+void
+runtime_LockOSThread(void)
+{
+       if(m == &runtime_m0 && runtime_sched.init) {
+               runtime_sched.lockmain = true;
+               return;
+       }
+       m->lockedg = g;
+       g->lockedm = m;
+}
 
 void
 runtime_UnlockOSThread(void)
 {
+       if(m == &runtime_m0 && runtime_sched.init) {
+               runtime_sched.lockmain = false;
+               return;
+       }
        m->lockedg = nil;
        g->lockedm = nil;
 }
index e28bc82..0044319 100644 (file)
@@ -318,16 +318,20 @@ void      runtime_startpanic(void);
 void   runtime_ready(G*);
 const byte*    runtime_getenv(const char*);
 int32  runtime_atoi(const byte*);
+uint32 runtime_fastrand1(void);
+
 void   runtime_sigprof(uint8 *pc, uint8 *sp, uint8 *lr, G *gp);
 void   runtime_resetcpuprofiler(int32);
 void   runtime_setcpuprofilerate(void(*)(uintptr*, int32), int32);
-uint32 runtime_fastrand1(void);
+void   runtime_usleep(uint32);
+
 void   runtime_semacquire(uint32 volatile *);
 void   runtime_semrelease(uint32 volatile *);
 int32  runtime_gomaxprocsfunc(int32 n);
 void   runtime_procyield(uint32);
 void   runtime_osyield(void);
-void   runtime_usleep(uint32);
+void   runtime_LockOSThread(void) __asm__("libgo_runtime.runtime.LockOSThread");
+void   runtime_UnlockOSThread(void) __asm__("libgo_runtime.runtime.UnlockOSThread");
 
 struct __go_func_type;
 void reflect_call(const struct __go_func_type *, const void *, _Bool, _Bool,