diff options
169 files changed, 2243 insertions, 1608 deletions
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index 74d9765c5d9..f63d1694922 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -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. diff --git a/libgo/config.h.in b/libgo/config.h.in index 0c1283cc574..f30af598168 100644 --- a/libgo/config.h.in +++ b/libgo/config.h.in @@ -33,18 +33,12 @@ /* 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 diff --git a/libgo/configure b/libgo/configure index e9f536a5883..2e99887e62d 100755 --- a/libgo/configure +++ b/libgo/configure @@ -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" diff --git a/libgo/configure.ac b/libgo/configure.ac index 576d1a64329..62d4c959991 100644 --- a/libgo/configure.ac +++ b/libgo/configure.ac @@ -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) diff --git a/libgo/go/archive/zip/struct.go b/libgo/go/archive/zip/struct.go index a32de5a9e0d..4f9f599a148 100644 --- a/libgo/go/archive/zip/struct.go +++ b/libgo/go/archive/zip/struct.go @@ -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) diff --git a/libgo/go/big/int.go b/libgo/go/big/int.go index b0dde1e6e37..db13d20f71c 100644 --- a/libgo/go/big/int.go +++ b/libgo/go/big/int.go @@ -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 { diff --git a/libgo/go/big/int_test.go b/libgo/go/big/int_test.go index fde19c23b72..d66bb5fa053 100644 --- a/libgo/go/big/int_test.go +++ b/libgo/go/big/int_test.go @@ -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) diff --git a/libgo/go/big/nat.go b/libgo/go/big/nat.go index c0769d88a91..fa0d7e72277 100644 --- a/libgo/go/big/nat.go +++ b/libgo/go/big/nat.go @@ -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) } diff --git a/libgo/go/big/nat_test.go b/libgo/go/big/nat_test.go index 4f5732824c5..ab34c6ec189 100644 --- a/libgo/go/big/nat_test.go +++ b/libgo/go/big/nat_test.go @@ -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}, diff --git a/libgo/go/big/rat.go b/libgo/go/big/rat.go index 6b860627206..1940a05494d 100644 --- a/libgo/go/big/rat.go +++ b/libgo/go/big/rat.go @@ -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 diff --git a/libgo/go/big/rat_test.go b/libgo/go/big/rat_test.go index a95e5fea3a5..24434504113 100644 --- a/libgo/go/big/rat_test.go +++ b/libgo/go/big/rat_test.go @@ -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) } diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go index 2ea7af3e25b..3a4e0ed8b02 100644 --- a/libgo/go/bufio/bufio.go +++ b/libgo/go/bufio/bufio.go @@ -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 } diff --git a/libgo/go/bufio/bufio_test.go b/libgo/go/bufio/bufio_test.go index 38213ffe788..4fd5f90b8ee 100644 --- a/libgo/go/bufio/bufio_test.go +++ b/libgo/go/bufio/bufio_test.go @@ -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) } } } diff --git a/libgo/go/bytes/buffer.go b/libgo/go/bytes/buffer.go index 975031bfa4f..c2a8c9fe59a 100644 --- a/libgo/go/bytes/buffer.go +++ b/libgo/go/bytes/buffer.go @@ -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 diff --git a/libgo/go/bytes/buffer_test.go b/libgo/go/bytes/buffer_test.go index 06d2a65c673..ee38e084a5c 100644 --- a/libgo/go/bytes/buffer_test.go +++ b/libgo/go/bytes/buffer_test.go @@ -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) diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go index 2fb456900a7..ac8320fe6b4 100644 --- a/libgo/go/bytes/bytes.go +++ b/libgo/go/bytes/bytes.go @@ -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:] diff --git a/libgo/go/bytes/bytes_test.go b/libgo/go/bytes/bytes_test.go index ce3f37e4de2..62f258de8ac 100644 --- a/libgo/go/bytes/bytes_test.go +++ b/libgo/go/bytes/bytes_test.go @@ -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, diff --git a/libgo/go/crypto/bcrypt/bcrypt_test.go b/libgo/go/crypto/bcrypt/bcrypt_test.go index 89eca0a4488..3efbc1c46f2 100644 --- a/libgo/go/crypto/bcrypt/bcrypt_test.go +++ b/libgo/go/crypto/bcrypt/bcrypt_test.go @@ -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 { diff --git a/libgo/go/crypto/openpgp/error/error.go b/libgo/go/crypto/openpgp/error/error.go index 3759ce16122..9cc21f1f8f6 100644 --- a/libgo/go/crypto/openpgp/error/error.go +++ b/libgo/go/crypto/openpgp/error/error.go @@ -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 diff --git a/libgo/go/crypto/rsa/rsa.go b/libgo/go/crypto/rsa/rsa.go index 6957659f284..3df88e06915 100644 --- a/libgo/go/crypto/rsa/rsa.go +++ b/libgo/go/crypto/rsa/rsa.go @@ -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") diff --git a/libgo/go/crypto/tls/alert.go b/libgo/go/crypto/tls/alert.go index 3b9e0e2415b..0856311e4cb 100644 --- a/libgo/go/crypto/tls/alert.go +++ b/libgo/go/crypto/tls/alert.go @@ -71,3 +71,7 @@ func (e alert) String() string { } return "alert(" + strconv.Itoa(int(e)) + ")" } + +func (e alert) Error() string { + return e.String() +} diff --git a/libgo/go/csv/reader.go b/libgo/go/csv/reader.go index 29ceeae85b4..a06b97894de 100644 --- a/libgo/go/csv/reader.go +++ b/libgo/go/csv/reader.go @@ -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 } diff --git a/libgo/go/csv/reader_test.go b/libgo/go/csv/reader_test.go index 967f96b8d1b..1b236059354 100644 --- a/libgo/go/csv/reader_test.go +++ b/libgo/go/csv/reader_test.go @@ -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 diff --git a/libgo/go/csv/writer.go b/libgo/go/csv/writer.go index ccf703f0f8c..98573c29fbe 100644 --- a/libgo/go/csv/writer.go +++ b/libgo/go/csv/writer.go @@ -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) } diff --git a/libgo/go/encoding/binary/binary_test.go b/libgo/go/encoding/binary/binary_test.go index b266996f635..ef20605a172 100644 --- a/libgo/go/encoding/binary/binary_test.go +++ b/libgo/go/encoding/binary/binary_test.go @@ -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 diff --git a/libgo/go/exp/ebnf/ebnf.go b/libgo/go/exp/ebnf/ebnf.go index 2ec7f00800d..7070cc79fde 100644 --- a/libgo/go/exp/ebnf/ebnf.go +++ b/libgo/go/exp/ebnf/ebnf.go @@ -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) diff --git a/libgo/go/exp/ebnf/parser.go b/libgo/go/exp/ebnf/parser.go index 2dbbefb7519..dac5dd8339f 100644 --- a/libgo/go/exp/ebnf/parser.go +++ b/libgo/go/exp/ebnf/parser.go @@ -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)) diff --git a/libgo/go/exp/gui/x11/conn.go b/libgo/go/exp/gui/x11/conn.go index bf94bcaabb4..f4a453ede4d 100644 --- a/libgo/go/exp/gui/x11/conn.go +++ b/libgo/go/exp/gui/x11/conn.go @@ -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 } diff --git a/libgo/go/exp/norm/composition.go b/libgo/go/exp/norm/composition.go index 1d722230d6f..7965ffc5742 100644 --- a/libgo/go/exp/norm/composition.go +++ b/libgo/go/exp/norm/composition.go @@ -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) } diff --git a/libgo/go/exp/norm/composition_test.go b/libgo/go/exp/norm/composition_test.go index ce9caaff160..e32380d7afa 100644 --- a/libgo/go/exp/norm/composition_test.go +++ b/libgo/go/exp/norm/composition_test.go @@ -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) { diff --git a/libgo/go/exp/norm/maketables.go b/libgo/go/exp/norm/maketables.go index 14718c5cd22..93edf221ef8 100644 --- a/libgo/go/exp/norm/maketables.go +++ b/libgo/go/exp/norm/maketables.go @@ -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. diff --git a/libgo/go/exp/norm/maketesttables.go b/libgo/go/exp/norm/maketesttables.go index fdcc114be23..20eb889ddef 100644 --- a/libgo/go/exp/norm/maketesttables.go +++ b/libgo/go/exp/norm/maketesttables.go @@ -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 diff --git a/libgo/go/exp/norm/normalize_test.go b/libgo/go/exp/norm/normalize_test.go index e374edf0abb..6bd5292d3fb 100644 --- a/libgo/go/exp/norm/normalize_test.go +++ b/libgo/go/exp/norm/normalize_test.go @@ -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 diff --git a/libgo/go/exp/norm/normregtest.go b/libgo/go/exp/norm/normregtest.go index cbd73ffa759..e747ddef763 100644 --- a/libgo/go/exp/norm/normregtest.go +++ b/libgo/go/exp/norm/normregtest.go @@ -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) diff --git a/libgo/go/exp/norm/trie_test.go b/libgo/go/exp/norm/trie_test.go index 5649fb7eea7..bbd5c03e7b3 100644 --- a/libgo/go/exp/norm/trie_test.go +++ b/libgo/go/exp/norm/trie_test.go @@ -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) diff --git a/libgo/go/exp/norm/triedata_test.go b/libgo/go/exp/norm/triedata_test.go index e8898e5d425..7f6276096c5 100644 --- a/libgo/go/exp/norm/triedata_test.go +++ b/libgo/go/exp/norm/triedata_test.go @@ -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. diff --git a/libgo/go/exp/norm/triegen.go b/libgo/go/exp/norm/triegen.go index 515e1c7860b..56cba321966 100644 --- a/libgo/go/exp/norm/triegen.go +++ b/libgo/go/exp/norm/triegen.go @@ -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 { diff --git a/libgo/go/exp/sql/convert_test.go b/libgo/go/exp/sql/convert_test.go index 88ba8e7a77a..849991868e1 100644 --- a/libgo/go/exp/sql/convert_test.go +++ b/libgo/go/exp/sql/convert_test.go @@ -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 { diff --git a/libgo/go/exp/ssh/client.go b/libgo/go/exp/ssh/client.go index 331138581fe..9eed3157ee7 100644 --- a/libgo/go/exp/ssh/client.go +++ b/libgo/go/exp/ssh/client.go @@ -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) + } } } } diff --git a/libgo/go/exp/ssh/messages.go b/libgo/go/exp/ssh/messages.go index 7771f2b242e..5f2c447142a 100644 --- a/libgo/go/exp/ssh/messages.go +++ b/libgo/go/exp/ssh/messages.go @@ -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: diff --git a/libgo/go/exp/ssh/server.go b/libgo/go/exp/ssh/server.go index 3a640fc081e..0dd24ecd6ee 100644 --- a/libgo/go/exp/ssh/server.go +++ b/libgo/go/exp/ssh/server.go @@ -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. + } } } diff --git a/libgo/go/exp/template/html/css.go b/libgo/go/exp/template/html/css.go index c22ec6df0d0..c26ae78d17f 100644 --- a/libgo/go/exp/template/html/css.go +++ b/libgo/go/exp/template/html/css.go @@ -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) } } diff --git a/libgo/go/exp/template/html/css_test.go b/libgo/go/exp/template/html/css_test.go index 5f633e89442..b3b83e855d3 100644 --- a/libgo/go/exp/template/html/css_test.go +++ b/libgo/go/exp/template/html/css_test.go @@ -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) } } diff --git a/libgo/go/exp/template/html/escape_test.go b/libgo/go/exp/template/html/escape_test.go index a4ea7596cd1..1b3b2567335 100644 --- a/libgo/go/exp/template/html/escape_test.go +++ b/libgo/go/exp/template/html/escape_test.go @@ -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) { diff --git a/libgo/go/exp/template/html/html.go b/libgo/go/exp/template/html/html.go index 91bb1b17049..92d8f419946 100644 --- a/libgo/go/exp/template/html/html.go +++ b/libgo/go/exp/template/html/html.go @@ -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) diff --git a/libgo/go/exp/template/html/js.go b/libgo/go/exp/template/html/js.go index 98c2ac5f27f..5646f8a4fd8 100644 --- a/libgo/go/exp/template/html/js.go +++ b/libgo/go/exp/template/html/js.go @@ -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 diff --git a/libgo/go/exp/types/exportdata.go b/libgo/go/exp/types/exportdata.go index 383520320f4..784ffff01a3 100644 --- a/libgo/go/exp/types/exportdata.go +++ b/libgo/go/exp/types/exportdata.go @@ -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 } diff --git a/libgo/go/exp/types/gcimporter.go b/libgo/go/exp/types/gcimporter.go index e744a63a96e..4e5172a3d22 100644 --- a/libgo/go/exp/types/gcimporter.go +++ b/libgo/go/exp/types/gcimporter.go @@ -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 index 00000000000..84a1abe2701 --- /dev/null +++ b/libgo/go/exp/types/testdata/test0.src @@ -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 +) diff --git a/libgo/go/exp/types/universe.go b/libgo/go/exp/types/universe.go index 80db1278295..f0435966d11 100644 --- a/libgo/go/exp/types/universe.go +++ b/libgo/go/exp/types/universe.go @@ -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") diff --git a/libgo/go/exp/winfsnotify/winfsnotify_test.go b/libgo/go/exp/winfsnotify/winfsnotify_test.go index 6e264d04f90..fb2b825e68e 100644 --- a/libgo/go/exp/winfsnotify/winfsnotify_test.go +++ b/libgo/go/exp/winfsnotify/winfsnotify_test.go @@ -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) diff --git a/libgo/go/expvar/expvar.go b/libgo/go/expvar/expvar.go index 7b733faf674..f5d6ed586c8 100644 --- a/libgo/go/expvar/expvar.go +++ b/libgo/go/expvar/expvar.go @@ -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, "}") diff --git a/libgo/go/fmt/doc.go b/libgo/go/fmt/doc.go index c993e57a40a..6713f0a16ed 100644 --- a/libgo/go/fmt/doc.go +++ b/libgo/go/fmt/doc.go @@ -89,10 +89,14 @@ 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: diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go index 38280d61f6b..db83f85f957 100644 --- a/libgo/go/fmt/fmt_test.go +++ b/libgo/go/fmt/fmt_test.go @@ -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) } diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go index 24b15a286b7..80eb9863353 100644 --- a/libgo/go/fmt/format.go +++ b/libgo/go/fmt/format.go @@ -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++ { diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go index 710baeec1d2..5e0237f4544 100644 --- a/libgo/go/fmt/print.go +++ b/libgo/go/fmt/print.go @@ -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: diff --git a/libgo/go/fmt/scan.go b/libgo/go/fmt/scan.go index 259451d02f7..eae952c9fff 100644 --- a/libgo/go/fmt/scan.go +++ b/libgo/go/fmt/scan.go @@ -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 } diff --git a/libgo/go/fmt/scan_test.go b/libgo/go/fmt/scan_test.go index 3f06e5725ca..fbc28c1b2bb 100644 --- a/libgo/go/fmt/scan_test.go +++ b/libgo/go/fmt/scan_test.go @@ -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 diff --git a/libgo/go/go/ast/ast.go b/libgo/go/go/ast/ast.go index 22bd5ee2266..f8caafc179a 100644 --- a/libgo/go/go/ast/ast.go +++ b/libgo/go/go/ast/ast.go @@ -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() diff --git a/libgo/go/go/ast/print.go b/libgo/go/go/ast/print.go index 62a30481d5c..e36f99fdf02 100644 --- a/libgo/go/go/ast/print.go +++ b/libgo/go/go/ast/print.go @@ -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++ { diff --git a/libgo/go/go/build/build_test.go b/libgo/go/go/build/build_test.go index 68a4180c906..398e31ce26f 100644 --- a/libgo/go/go/build/build_test.go +++ b/libgo/go/go/build/build_test.go @@ -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"}, diff --git a/libgo/go/go/build/dir.go b/libgo/go/go/build/dir.go index 3ee10ab3484..b67f999b766 100644 --- a/libgo/go/go/build/dir.go +++ b/libgo/go/go/build/dir.go @@ -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 { diff --git a/libgo/go/go/build/pkgtest/pkgtest.go b/libgo/go/go/build/pkgtest/pkgtest.go index 03ebb9893aa..08eea1e2bc3 100644 --- a/libgo/go/go/build/pkgtest/pkgtest.go +++ b/libgo/go/go/build/pkgtest/pkgtest.go @@ -4,9 +4,9 @@ package pkgtest -import "os" +import "bytes" -func Foo() os.Error { +func Foo() *bytes.Buffer { return nil } diff --git a/libgo/go/go/doc/doc.go b/libgo/go/go/doc/doc.go index c7fed97841c..91748643391 100644 --- a/libgo/go/go/doc/doc.go +++ b/libgo/go/go/doc/doc.go @@ -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 } diff --git a/libgo/go/go/parser/parser.go b/libgo/go/go/parser/parser.go index be82b2f801a..e2c94413721 100644 --- a/libgo/go/go/parser/parser.go +++ b/libgo/go/go/parser/parser.go @@ -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 diff --git a/libgo/go/go/parser/parser_test.go b/libgo/go/go/parser/parser_test.go index 9705dcff250..dee90fbcf4c 100644 --- a/libgo/go/go/parser/parser_test.go +++ b/libgo/go/go/parser/parser_test.go @@ -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) + } + } +} diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go index 364530634aa..248e43d4e72 100644 --- a/libgo/go/go/printer/nodes.go +++ b/libgo/go/go/printer/nodes.go @@ -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 { diff --git a/libgo/go/go/scanner/errors.go b/libgo/go/go/scanner/errors.go index a0927e4167f..df2a46bc226 100644 --- a/libgo/go/go/scanner/errors.go +++ b/libgo/go/go/scanner/errors.go @@ -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 diff --git a/libgo/go/go/scanner/scanner.go b/libgo/go/go/scanner/scanner.go index 589ec68a678..dfbdaa3a125 100644 --- a/libgo/go/go/scanner/scanner.go +++ b/libgo/go/go/scanner/scanner.go @@ -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 diff --git a/libgo/go/go/scanner/scanner_test.go b/libgo/go/go/scanner/scanner_test.go index 0c2cbe6dc02..7ed927a49fa 100644 --- a/libgo/go/go/scanner/scanner_test.go +++ b/libgo/go/go/scanner/scanner_test.go @@ -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 { diff --git a/libgo/go/gob/codec_test.go b/libgo/go/gob/codec_test.go index 2bcbf82a309..5306354bf2a 100644 --- a/libgo/go/gob/codec_test.go +++ b/libgo/go/gob/codec_test.go @@ -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 } diff --git a/libgo/go/gob/decode.go b/libgo/go/gob/decode.go index f480087836e..d027d3f1a4b 100644 --- a/libgo/go/gob/decode.go +++ b/libgo/go/gob/decode.go @@ -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)) diff --git a/libgo/go/gob/decoder.go b/libgo/go/gob/decoder.go index 5efcea8bc16..1d526e35c0f 100644 --- a/libgo/go/gob/decoder.go +++ b/libgo/go/gob/decoder.go @@ -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. diff --git a/libgo/go/gob/encode.go b/libgo/go/gob/encode.go index 6bb54588098..c16443553ce 100644 --- a/libgo/go/gob/encode.go +++ b/libgo/go/gob/encode.go @@ -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 } diff --git a/libgo/go/gob/encoder_test.go b/libgo/go/gob/encoder_test.go index a774438d388..98c0c977578 100644 --- a/libgo/go/gob/encoder_test.go +++ b/libgo/go/gob/encoder_test.go @@ -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) diff --git a/libgo/go/gob/error.go b/libgo/go/gob/error.go index bfd38fc16d3..106543d7360 100644 --- a/libgo/go/gob/error.go +++ b/libgo/go/gob/error.go @@ -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 } diff --git a/libgo/go/html/entity.go b/libgo/go/html/entity.go index 21263e22d8c..bd830752359 100644 --- a/libgo/go/html/entity.go +++ b/libgo/go/html/entity.go @@ -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'}, diff --git a/libgo/go/html/escape.go b/libgo/go/html/escape.go index e9edc474da5..69e0028e445 100644 --- a/libgo/go/html/escape.go +++ b/libgo/go/html/escape.go @@ -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 != ';' { diff --git a/libgo/go/html/node.go b/libgo/go/html/node.go index 4ecfd6ca238..5ca6035c118 100644 --- a/libgo/go/html/node.go +++ b/libgo/go/html/node.go @@ -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-- { diff --git a/libgo/go/html/parse.go b/libgo/go/html/parse.go index 530942aa8f0..54f7e2e8a55 100644 --- a/libgo/go/html/parse.go +++ b/libgo/go/html/parse.go @@ -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": diff --git a/libgo/go/html/parse_test.go b/libgo/go/html/parse_test.go index b0ddd924762..b9572fa1234 100644 --- a/libgo/go/html/parse_test.go +++ b/libgo/go/html/parse_test.go @@ -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, +} diff --git a/libgo/go/html/render.go b/libgo/go/html/render.go index d5dc4484333..0522b6ef92a 100644 --- a/libgo/go/html/render.go +++ b/libgo/go/html/render.go @@ -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) diff --git a/libgo/go/html/token_test.go b/libgo/go/html/token_test.go index 45ce85e9115..a5efdf2d498 100644 --- a/libgo/go/html/token_test.go +++ b/libgo/go/html/token_test.go @@ -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()) } } } diff --git a/libgo/go/http/cgi/host.go b/libgo/go/http/cgi/host.go index 9ea4c9d8bf2..365a712dfa8 100644 --- a/libgo/go/http/cgi/host.go +++ b/libgo/go/http/cgi/host.go @@ -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 } diff --git a/libgo/go/http/reverseproxy.go b/libgo/go/http/reverseproxy.go index 3f8bfdc80c2..3a63db009fc 100644 --- a/libgo/go/http/reverseproxy.go +++ b/libgo/go/http/reverseproxy.go @@ -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) diff --git a/libgo/go/http/reverseproxy_test.go b/libgo/go/http/reverseproxy_test.go index 8078c8d10df..663218d61b9 100644 --- a/libgo/go/http/reverseproxy_test.go +++ b/libgo/go/http/reverseproxy_test.go @@ -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) diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go index 55206348e42..07e2bce76a6 100644 --- a/libgo/go/io/io.go +++ b/libgo/go/io/io.go @@ -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 diff --git a/libgo/go/json/decode.go b/libgo/go/json/decode.go index 31b15a400df..800df985abc 100644 --- a/libgo/go/json/decode.go +++ b/libgo/go/json/decode.go @@ -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 diff --git a/libgo/go/json/decode_test.go b/libgo/go/json/decode_test.go index 2c7cbc4a290..d745e8dd26f 100644 --- a/libgo/go/json/decode_test.go +++ b/libgo/go/json/decode_test.go @@ -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": "" }, diff --git a/libgo/go/json/encode.go b/libgo/go/json/encode.go index 46abe4360ed..ba5c15cc496 100644 --- a/libgo/go/json/encode.go +++ b/libgo/go/json/encode.go @@ -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) diff --git a/libgo/go/json/encode_test.go b/libgo/go/json/encode_test.go index f85bb6216a2..92f266aba63 100644 --- a/libgo/go/json/encode_test.go +++ b/libgo/go/json/encode_test.go @@ -28,7 +28,7 @@ type Optionals struct { var optionalsExpected = `{ "sr": "", "omitempty": 0, - "slr": [], + "slr": null, "mr": {} }` diff --git a/libgo/go/json/scanner.go b/libgo/go/json/scanner.go index 49c2edd5453..1a39b4cb34d 100644 --- a/libgo/go/json/scanner.go +++ b/libgo/go/json/scanner.go @@ -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' } diff --git a/libgo/go/json/scanner_test.go b/libgo/go/json/scanner_test.go index 4d73eac8aaa..40bf2951778 100644 --- a/libgo/go/json/scanner_test.go +++ b/libgo/go/json/scanner_test.go @@ -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) } diff --git a/libgo/go/json/stream.go b/libgo/go/json/stream.go index f143b3f0ade..98cb7935df1 100644 --- a/libgo/go/json/stream.go +++ b/libgo/go/json/stream.go @@ -115,7 +115,7 @@ Input: func nonSpace(b []byte) bool { for _, c := range b { - if !isSpace(int(c)) { + if !isSpace(rune(c)) { return true } } diff --git a/libgo/go/mail/message.go b/libgo/go/mail/message.go index e227d17d6fa..29249fbde17 100644 --- a/libgo/go/mail/message.go +++ b/libgo/go/mail/message.go @@ -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": diff --git a/libgo/go/math/all_test.go b/libgo/go/math/all_test.go index 94ddea2bfcb..b540b179323 100644 --- a/libgo/go/math/all_test.go +++ b/libgo/go/math/all_test.go @@ -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]) } } diff --git a/libgo/go/math/sin.go b/libgo/go/math/sin.go index 8a2edd7e563..9e553a268bd 100644 --- a/libgo/go/math/sin.go +++ b/libgo/go/math/sin.go @@ -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 +} diff --git a/libgo/go/mime/grammar.go b/libgo/go/mime/grammar.go index 70a94cd807f..e16a06c86be 100644 --- a/libgo/go/mime/grammar.go +++ b/libgo/go/mime/grammar.go @@ -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 } diff --git a/libgo/go/mime/mediatype.go b/libgo/go/mime/mediatype.go index b0d39338170..8ad80044350 100644 --- a/libgo/go/mime/mediatype.go +++ b/libgo/go/mime/mediatype.go @@ -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 } diff --git a/libgo/go/net/lookup_plan9.go b/libgo/go/net/lookup_plan9.go index d779f4a5d71..a14c592e8f6 100644 --- a/libgo/go/net/lookup_plan9.go +++ b/libgo/go/net/lookup_plan9.go @@ -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 diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go index c0fcd260472..6b7e53d0c6c 100644 --- a/libgo/go/net/lookup_test.go +++ b/libgo/go/net/lookup_test.go @@ -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 { diff --git a/libgo/go/net/net_test.go b/libgo/go/net/net_test.go index b4a6e1f5d69..51cdac91bef 100644 --- a/libgo/go/net/net_test.go +++ b/libgo/go/net/net_test.go @@ -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 { diff --git a/libgo/go/net/sock_windows.go b/libgo/go/net/sock_windows.go index 5169d1e6a29..9b9cd9e368b 100644 --- a/libgo/go/net/sock_windows.go +++ b/libgo/go/net/sock_windows.go @@ -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) diff --git a/libgo/go/net/tcpsock_plan9.go b/libgo/go/net/tcpsock_plan9.go index f4f6e9fee16..3319e57c338 100644 --- a/libgo/go/net/tcpsock_plan9.go +++ b/libgo/go/net/tcpsock_plan9.go @@ -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. diff --git a/libgo/go/net/textproto/reader.go b/libgo/go/net/textproto/reader.go index ece9a99ffbb..98b39276b8a 100644 --- a/libgo/go/net/textproto/reader.go +++ b/libgo/go/net/textproto/reader.go @@ -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, diff --git a/libgo/go/net/textproto/reader_test.go b/libgo/go/net/textproto/reader_test.go index 23ebc3f61e8..a087e29d914 100644 --- a/libgo/go/net/textproto/reader_test.go +++ b/libgo/go/net/textproto/reader_test.go @@ -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 diff --git a/libgo/go/net/timeout_test.go b/libgo/go/net/timeout_test.go index 0dbab5846a6..2c2c36fff5e 100644 --- a/libgo/go/net/timeout_test.go +++ b/libgo/go/net/timeout_test.go @@ -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) diff --git a/libgo/go/old/regexp/regexp.go b/libgo/go/old/regexp/regexp.go index e8d4c087cf8..f18d9c8f592 100644 --- a/libgo/go/old/regexp/regexp.go +++ b/libgo/go/old/regexp/regexp.go @@ -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++ } diff --git a/libgo/go/old/template/parse.go b/libgo/go/old/template/parse.go index dedf9ad8e9f..9f8d1eba338 100644 --- a/libgo/go/old/template/parse.go +++ b/libgo/go/old/template/parse.go @@ -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 } diff --git a/libgo/go/os/file.go b/libgo/go/os/file.go index 4335d45e5a0..9f982e183a2 100644 --- a/libgo/go/os/file.go +++ b/libgo/go/os/file.go @@ -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) { diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go index 3277fc22bfa..b8c4967b12d 100644 --- a/libgo/go/os/os_test.go +++ b/libgo/go/os/os_test.go @@ -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() diff --git a/libgo/go/path/filepath/match.go b/libgo/go/path/filepath/match.go index 0ccc87e6560..15c84a7e985 100644 --- a/libgo/go/path/filepath/match.go +++ b/libgo/go/path/filepath/match.go @@ -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 diff --git a/libgo/go/path/match.go b/libgo/go/path/match.go index efb8c5ce7fc..e9d032799fe 100644 --- a/libgo/go/path/match.go +++ b/libgo/go/path/match.go @@ -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 diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go index 696bd56637e..98b6e23c1d0 100644 --- a/libgo/go/reflect/all_test.go +++ b/libgo/go/reflect/all_test.go @@ -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") diff --git a/libgo/go/regexp/exec.go b/libgo/go/regexp/exec.go index 3b0e3888524..d7057a191b7 100644 --- a/libgo/go/regexp/exec.go +++ b/libgo/go/regexp/exec.go @@ -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] diff --git a/libgo/go/regexp/regexp.go b/libgo/go/regexp/regexp.go index 2325f6204b1..a1b7951bfe8 100644 --- a/libgo/go/regexp/regexp.go +++ b/libgo/go/regexp/regexp.go @@ -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 diff --git a/libgo/go/regexp/syntax/compile.go b/libgo/go/regexp/syntax/compile.go index c415d39a57e..c90de3fe99d 100644 --- a/libgo/go/regexp/syntax/compile.go +++ b/libgo/go/regexp/syntax/compile.go @@ -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 } diff --git a/libgo/go/regexp/syntax/parse.go b/libgo/go/regexp/syntax/parse.go index 7013459019c..bb19c5ad55c 100644 --- a/libgo/go/regexp/syntax/parse.go +++ b/libgo/go/regexp/syntax/parse.go @@ -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' } diff --git a/libgo/go/regexp/syntax/parse_test.go b/libgo/go/regexp/syntax/parse_test.go index 5d9085bfb1f..88f65ecfc9b 100644 --- a/libgo/go/regexp/syntax/parse_test.go +++ b/libgo/go/regexp/syntax/parse_test.go @@ -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') } diff --git a/libgo/go/regexp/syntax/perl_groups.go b/libgo/go/regexp/syntax/perl_groups.go index 05b392c40d8..1a11ca62f0c 100644 --- a/libgo/go/regexp/syntax/perl_groups.go +++ b/libgo/go/regexp/syntax/perl_groups.go @@ -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, diff --git a/libgo/go/regexp/syntax/prog.go b/libgo/go/regexp/syntax/prog.go index ced45da077b..f5b697a59ae 100644 --- a/libgo/go/regexp/syntax/prog.go +++ b/libgo/go/regexp/syntax/prog.go @@ -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 diff --git a/libgo/go/regexp/syntax/regexp.go b/libgo/go/regexp/syntax/regexp.go index 033848df28a..b5ddab1d16b 100644 --- a/libgo/go/regexp/syntax/regexp.go +++ b/libgo/go/regexp/syntax/regexp.go @@ -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(`}`) } } diff --git a/libgo/go/rpc/jsonrpc/all_test.go b/libgo/go/rpc/jsonrpc/all_test.go index c1a9e8ecbc5..99253baf3cb 100644 --- a/libgo/go/rpc/jsonrpc/all_test.go +++ b/libgo/go/rpc/jsonrpc/all_test.go @@ -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") +} diff --git a/libgo/go/rpc/server.go b/libgo/go/rpc/server.go index f03710061a4..71797e2e5a9 100644 --- a/libgo/go/rpc/server.go +++ b/libgo/go/rpc/server.go @@ -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) diff --git a/libgo/go/rpc/server_test.go b/libgo/go/rpc/server_test.go index 029741b28b5..3e9fe297d45 100644 --- a/libgo/go/rpc/server_test.go +++ b/libgo/go/rpc/server_test.go @@ -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 } diff --git a/libgo/go/runtime/debug.go b/libgo/go/runtime/debug.go index 6370a57d802..124370384c0 100644 --- a/libgo/go/runtime/debug.go +++ b/libgo/go/runtime/debug.go @@ -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. diff --git a/libgo/go/runtime/pprof/pprof.go b/libgo/go/runtime/pprof/pprof.go index fdeceb4e8dc..70228964545 100644 --- a/libgo/go/runtime/pprof/pprof.go +++ b/libgo/go/runtime/pprof/pprof.go @@ -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. diff --git a/libgo/go/scanner/scanner.go b/libgo/go/scanner/scanner.go index 29e5f8c7428..3594db997dd 100644 --- a/libgo/go/scanner/scanner.go +++ b/libgo/go/scanner/scanner.go @@ -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 diff --git a/libgo/go/scanner/scanner_test.go b/libgo/go/scanner/scanner_test.go index bbbba128348..fb398831e10 100644 --- a/libgo/go/scanner/scanner_test.go +++ b/libgo/go/scanner/scanner_test.go @@ -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 { diff --git a/libgo/go/smtp/smtp_test.go b/libgo/go/smtp/smtp_test.go index c053557d7f4..553d3ae0991 100644 --- a/libgo/go/smtp/smtp_test.go +++ b/libgo/go/smtp/smtp_test.go @@ -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() diff --git a/libgo/go/strconv/atob.go b/libgo/go/strconv/atob.go index 98ce750798d..720819490cb 100644 --- a/libgo/go/strconv/atob.go +++ b/libgo/go/strconv/atob.go @@ -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 diff --git a/libgo/go/strconv/atob_test.go b/libgo/go/strconv/atob_test.go index 541e60d1e9e..d9db6c7c0af 100644 --- a/libgo/go/strconv/atob_test.go +++ b/libgo/go/strconv/atob_test.go @@ -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}, diff --git a/libgo/go/strconv/atof.go b/libgo/go/strconv/atof.go index 86c56f7fd7e..4a4b1b43ce2 100644 --- a/libgo/go/strconv/atof.go +++ b/libgo/go/strconv/atof.go @@ -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 } diff --git a/libgo/go/strconv/atof_test.go b/libgo/go/strconv/atof_test.go index 23aafc1e5d7..33f881c7fd6 100644 --- a/libgo/go/strconv/atof_test.go +++ b/libgo/go/strconv/atof_test.go @@ -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}, diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go index 58459421623..92ba89daea4 100644 --- a/libgo/go/strconv/atoi.go +++ b/libgo/go/strconv/atoi.go @@ -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 } diff --git a/libgo/go/strconv/atoi_test.go b/libgo/go/strconv/atoi_test.go index 0b9f2955376..0d2e38117a3 100644 --- a/libgo/go/strconv/atoi_test.go +++ b/libgo/go/strconv/atoi_test.go @@ -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() { diff --git a/libgo/go/strconv/fp_test.go b/libgo/go/strconv/fp_test.go index 3096957f5d3..991d3ac1e43 100644 --- a/libgo/go/strconv/fp_test.go +++ b/libgo/go/strconv/fp_test.go @@ -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() diff --git a/libgo/go/strconv/quote.go b/libgo/go/strconv/quote.go index bbb9783ce8d..7efdcfedb22 100644 --- a/libgo/go/strconv/quote.go +++ b/libgo/go/strconv/quote.go @@ -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 diff --git a/libgo/go/strconv/quote_test.go b/libgo/go/strconv/quote_test.go index 0311f77a3a7..9a597700d27 100644 --- a/libgo/go/strconv/quote_test.go +++ b/libgo/go/strconv/quote_test.go @@ -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) } } } diff --git a/libgo/go/strings/reader.go b/libgo/go/strings/reader.go index eb515de0067..f4385a437ab 100644 --- a/libgo/go/strings/reader.go +++ b/libgo/go/strings/reader.go @@ -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 } diff --git a/libgo/go/strings/replace_test.go b/libgo/go/strings/replace_test.go index e337856c64d..23c7e2e5334 100644 --- a/libgo/go/strings/replace_test.go +++ b/libgo/go/strings/replace_test.go @@ -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 } diff --git a/libgo/go/strings/strings.go b/libgo/go/strings/strings.go index 58301febdf8..4f6e8a6fe3e 100644 --- a/libgo/go/strings/strings.go +++ b/libgo/go/strings/strings.go @@ -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:] diff --git a/libgo/go/strings/strings_test.go b/libgo/go/strings/strings_test.go index 0859ddd9623..4132996c192 100644 --- a/libgo/go/strings/strings_test.go +++ b/libgo/go/strings/strings_test.go @@ -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) } } } diff --git a/libgo/go/template/exec.go b/libgo/go/template/exec.go index e7fad72fe71..34c6633232f 100644 --- a/libgo/go/template/exec.go +++ b/libgo/go/template/exec.go @@ -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) diff --git a/libgo/go/template/exec_test.go b/libgo/go/template/exec_test.go index 50b0ad2b75f..2d2b4029423 100644 --- a/libgo/go/template/exec_test.go +++ b/libgo/go/template/exec_test.go @@ -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 } diff --git a/libgo/go/template/funcs.go b/libgo/go/template/funcs.go index feb1fd82c72..938559eec96 100644 --- a/libgo/go/template/funcs.go +++ b/libgo/go/template/funcs.go @@ -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 diff --git a/libgo/go/template/parse/lex.go b/libgo/go/template/parse/lex.go index 16ff590d3b4..04c105d1610 100644 --- a/libgo/go/template/parse/lex.go +++ b/libgo/go/template/parse/lex.go @@ -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) } diff --git a/libgo/go/testing/quick/quick.go b/libgo/go/testing/quick/quick.go index 756a60e1352..9ec1925de3d 100644 --- a/libgo/go/testing/quick/quick.go +++ b/libgo/go/testing/quick/quick.go @@ -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: diff --git a/libgo/go/time/format.go b/libgo/go/time/format.go index 50e96a5c259..1a629c91885 100644 --- a/libgo/go/time/format.go +++ b/libgo/go/time/format.go @@ -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" diff --git a/libgo/go/time/time_test.go b/libgo/go/time/time_test.go index 353976c9693..e4cf51374cb 100644 --- a/libgo/go/time/time_test.go +++ b/libgo/go/time/time_test.go @@ -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}, diff --git a/libgo/go/unicode/digit.go b/libgo/go/unicode/digit.go index 6793fd7e5f8..4800bd6ea8e 100644 --- a/libgo/go/unicode/digit.go +++ b/libgo/go/unicode/digit.go @@ -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) } diff --git a/libgo/go/unicode/digit_test.go b/libgo/go/unicode/digit_test.go index ae3c0ece93f..551c42a24ee 100644 --- a/libgo/go/unicode/digit_test.go +++ b/libgo/go/unicode/digit_test.go @@ -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) } diff --git a/libgo/go/unicode/graphic.go b/libgo/go/unicode/graphic.go index d482aace26e..9343bc9b0a9 100644 --- a/libgo/go/unicode/graphic.go +++ b/libgo/go/unicode/graphic.go @@ -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) } diff --git a/libgo/go/unicode/graphic_test.go b/libgo/go/unicode/graphic_test.go index 77c679f7ce0..7b1f6209e80 100644 --- a/libgo/go/unicode/graphic_test.go +++ b/libgo/go/unicode/graphic_test.go @@ -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 { diff --git a/libgo/go/unicode/letter.go b/libgo/go/unicode/letter.go index 38a11c42bf6..01c485b6931 100644 --- a/libgo/go/unicode/letter.go +++ b/libgo/go/unicode/letter.go @@ -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) } diff --git a/libgo/go/unicode/letter_test.go b/libgo/go/unicode/letter_test.go index 8d2665a44fc..2d80562182c 100644 --- a/libgo/go/unicode/letter_test.go +++ b/libgo/go/unicode/letter_test.go @@ -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 } } } diff --git a/libgo/go/unicode/script_test.go b/libgo/go/unicode/script_test.go index dfd636d8399..1c5b801426f 100644 --- a/libgo/go/unicode/script_test.go +++ b/libgo/go/unicode/script_test.go @@ -10,7 +10,7 @@ import ( ) type T struct { - rune int + rune rune script string } diff --git a/libgo/go/utf16/utf16.go b/libgo/go/utf16/utf16.go index 372e38a7181..2b2eb28f2df 100644 --- a/libgo/go/utf16/utf16.go +++ b/libgo/go/utf16/utf16.go @@ -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++ } } diff --git a/libgo/go/utf16/utf16_test.go b/libgo/go/utf16/utf16_test.go index 2b9fb3d87dc..7ea290a5299 100644 --- a/libgo/go/utf16/utf16_test.go +++ b/libgo/go/utf16/utf16_test.go @@ -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, "]") -} diff --git a/libgo/go/utf8/string.go b/libgo/go/utf8/string.go index 83b56b9448e..b33347950fc 100644 --- a/libgo/go/utf8/string.go +++ b/libgo/go/utf8/string.go @@ -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 diff --git a/libgo/go/utf8/string_test.go b/libgo/go/utf8/string_test.go index f376b628c73..920d2a0ea31 100644 --- a/libgo/go/utf8/string_test.go +++ b/libgo/go/utf8/string_test.go @@ -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()) diff --git a/libgo/go/utf8/utf8.go b/libgo/go/utf8/utf8.go index 3cd919d1d98..a5f9983b332 100644 --- a/libgo/go/utf8/utf8.go +++ b/libgo/go/utf8/utf8.go @@ -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 diff --git a/libgo/go/utf8/utf8_test.go b/libgo/go/utf8/utf8_test.go index 6cbbebc1a37..857bcf6e1a6 100644 --- a/libgo/go/utf8/utf8_test.go +++ b/libgo/go/utf8/utf8_test.go @@ -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 diff --git a/libgo/go/xml/marshal_test.go b/libgo/go/xml/marshal_test.go index ad3aa97e25f..eb358d5dcce 100644 --- a/libgo/go/xml/marshal_test.go +++ b/libgo/go/xml/marshal_test.go @@ -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) } } } diff --git a/libgo/go/xml/read.go b/libgo/go/xml/read.go index f64e1300189..1fe20ac6147 100644 --- a/libgo/go/xml/read.go +++ b/libgo/go/xml/read.go @@ -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) } diff --git a/libgo/go/xml/xml.go b/libgo/go/xml/xml.go index 85c24bc4503..bc03c8e0d49 100644 --- a/libgo/go/xml/xml.go +++ b/libgo/go/xml/xml.go @@ -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 "" } diff --git a/libgo/runtime/go-main.c b/libgo/runtime/go-main.c index 8047eaea93f..45467ed06c0 100644 --- a/libgo/runtime/go-main.c +++ b/libgo/runtime/go-main.c @@ -32,10 +32,7 @@ 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 (); } diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c index b243de2424e..e5c01f550e6 100644 --- a/libgo/runtime/proc.c +++ b/libgo/runtime/proc.c @@ -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; } diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h index e28bc82f8ab..00443197095 100644 --- a/libgo/runtime/runtime.h +++ b/libgo/runtime/runtime.h @@ -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, |