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
sub = sub.substr(4);
ret->append(sub);
}
+ ret->push_back(' ');
}
- ret->append(" }");
+ ret->append("}");
}
// Mangled name.
/* 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
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"
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)
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)
return x.abs.decimalString()
}
-func charset(ch int) string {
+func charset(ch rune) string {
switch ch {
case 'b':
return lowercaseDigits[0:2]
// 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
// 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 {
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)
// 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)
}
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},
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
_, 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)
}
// 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()
}
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
// 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
}
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
}
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)
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 {
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)
}
}
}
// 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
// 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.
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
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 {
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 {
// 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)
// 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
// 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
}
}
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
}
}
// 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++
}
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
// 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.
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
}
// 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.
// 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)
// 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
// 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:])
// 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
// 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
}
}
}
// 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)
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:]
}
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{}},
}
}
-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) {
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 {
}
// 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 {
}
// 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
}
}
}
-func runesEqual(a, b []int) bool {
+func runesEqual(a, b []rune) bool {
if len(a) != len(b) {
return false
}
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) {
}
type predicate struct {
- f func(r int) bool
+ f func(r rune) bool
name string
}
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",
func not(p predicate) predicate {
return predicate{
- func(r int) bool {
+ func(r rune) bool {
return !p.f(r)
},
"not " + p.name,
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 {
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
// [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")
}
return "alert(" + strconv.Itoa(int(e)) + ")"
}
+
+func (e alert) Error() string {
+ return e.String()
+}
//
// 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
// 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.
}
// 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
}
}
// 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()
// 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
}
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 {
}
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)
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)
}
}
// 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
}
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
//
// 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
}
return
}
- for _, rune := range field {
- switch rune {
+ for _, r1 := range field {
+ switch r1 {
case '"':
_, err = w.w.WriteString(`""`)
case '\r':
err = w.w.WriteByte('\n')
}
default:
- _, err = w.w.WriteRune(rune)
+ _, err = w.w.WriteRune(r1)
}
if err != nil {
return
return true
}
- rune, _ := utf8.DecodeRuneInString(field)
- return unicode.IsSpace(rune)
+ r1, _ := utf8.DecodeRuneInString(field)
+ return unicode.IsSpace(r1)
}
package binary
import (
- "io"
- "os"
"bytes"
+ "io"
"math"
+ "os"
"reflect"
"testing"
)
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
}
}
-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)
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
}
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))
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
}
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
}
}
if err := c.w.Flush(); err != nil {
if err != os.EOF {
- log.Println("x11:", err.String())
+ log.Println("x11:", err)
}
return
}
}
// 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.
// 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)
}
// 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))
}
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)
}
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)
}
}
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) {
}
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) {
}
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) {
// 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
SMissing
)
-var lastChar int = 0
+var lastChar = rune('\u0000')
func (c Char) isValid() bool {
return c.codePoint != 0 && c.state != SMissing
return buf.String()
}
-type Decomposition []int
+type Decomposition []rune
func (d Decomposition) String() string {
return fmt.Sprintf("%.4X", d)
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:]
if err != nil {
return a, err
}
- a = append(a, int(point))
+ a = append(a, rune(point))
}
return a, nil
}
state = SLast
}
firstChar := lastChar + 1
- lastChar = int(point)
+ lastChar = rune(point)
if state != SLast {
firstChar = lastChar
}
// 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
}
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-- {
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)
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
}
}
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
for i, char := range chars {
v := makeCharInfo(char)
if v != 0 {
- t.insert(i, v)
+ t.insert(rune(i), v)
}
}
return t.printTables("charInfo")
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)))
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 {
}
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 {
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)
}
}
}
-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.
// 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
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)
}
}
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
"path"
"regexp"
"runtime"
- "strings"
"strconv"
+ "strings"
"time"
"utf8"
)
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.
}
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])
}
}
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)
}
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)
}
}
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)
{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)
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)
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)
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)
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.
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 {
{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 {
// 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)
+ }
}
}
}
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
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:
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.
+ }
}
}
}
// 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.
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"
}
// 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))
}
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)
}
}
func TestIsCSSNmchar(t *testing.T) {
tests := []struct {
- rune int
+ rune rune
want bool
}{
{0, false},
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)
}
}
}
}
-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())
}
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) {
}
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) {
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)
// 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:])] {
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`
// 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
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
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
}
// 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
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)
}
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++
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
--- /dev/null
+// 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
+)
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")
// 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)
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, "}")
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:
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))
}
{"%#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]`},
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) {
}
// Value receiver.
-func (p PanicF) Format(f State, c int) {
+func (p PanicF) Format(f State, c rune) {
panic(p.message)
}
}
// 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
j++
buf[j] = '\''
j++
- utf8.EncodeRune(buf[j:], int(a))
+ utf8.EncodeRune(buf[j:], rune(a))
j += runeWidth
buf[j] = '\''
}
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++ {
}
// 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++ {
// 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,
return false
}
-func (p *pp) add(c int) {
+func (p *pp) add(c rune) {
p.buf.WriteRune(c)
}
p.buf.WriteByte('?')
}
-func (p *pp) badVerb(verb int) {
+func (p *pp) badVerb(verb rune) {
p.add('%')
p.add('!')
p.add(verb)
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)
// 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)
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)
}
}
-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)
}
}
-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)
}
}
-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)
}
}
-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)
}
}
-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 {
}
}
-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)
}
}
-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:
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
}
}
-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
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
}
}
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)
}
// 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)
// 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:
// 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
// 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)
// 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
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
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
}
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
}
// 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
// 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
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 {
}
// notSpace is the default scanning function used in Token.
-func notSpace(r int) bool {
+func notSpace(r rune) bool {
return !unicode.IsSpace(r)
}
// 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
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])
}
// 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
}
s.errorString("unexpected newline")
return
}
- if !unicode.IsSpace(rune) {
+ if !unicode.IsSpace(r) {
s.UnreadRune()
break
}
// 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()
}
// 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
// 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()
}
// 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
}
// 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") {
)
// 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
// 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,
// 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)
}
// 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))
}
// 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
}
// 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 ""
}
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
}
}
}
// 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'
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.
// 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
}
// 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
}
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
}
// 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 {
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
if err != nil {
return
}
- var c int
- c, _, err = b.ReadRune()
+ c, _, err := b.ReadRune()
if err != nil {
if err == os.EOF {
err = nil
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
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()
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)
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)
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++ {
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"},
//
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 {
package pkgtest
-import "os"
+import "bytes"
-func Foo() os.Error {
+func Foo() *bytes.Buffer {
return nil
}
}
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
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
}
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
} else {
y = p.parseRhsList()
}
+ if tok == token.DEFINE {
+ p.shortVarDecl(p.makeIdentList(x))
+ }
return &ast.AssignStmt{x, pos, tok, y}, isRange
}
}
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 {
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
package parser
import (
+ "go/ast"
"go/token"
"os"
"testing"
}
}
}
+
+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)
+ }
+ }
+}
}
p.expr(s.Path, multiLine)
p.setComment(s.Comment)
+ p.print(s.EndPos)
case *ast.ValueSpec:
if n != 1 {
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
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
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")
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)
}
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
}
return tok
}
-func (S *Scanner) scanEscape(quote int) {
+func (S *Scanner) scanEscape(quote rune) {
offs := S.offset
var i, base, max uint32
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
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
}
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)
}
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)
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
}
_, 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 {
// 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
}
}
}
if op == nil {
- errorf("decode can't handle type %s", rt.String())
+ errorf("decode can't handle type %s", rt)
}
return &op, indir
}
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))
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.
}
}
if op == nil {
- errorf("can't happen: encode type %s", rt.String())
+ errorf("can't happen: encode type %s", rt)
}
return &op, indir
}
}
// 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)
// 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.
// 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
}
//
// 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',
}
// 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'},
// 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',
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 != ';' {
*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-- {
import (
"io"
"os"
+ "strings"
)
// A parser implements the HTML5 parsing algorithm:
// 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-- {
return inHeadIM, !implied
}
+const whitespace = " \t\r\n\f"
+
// Section 11.2.5.4.4.
func inHeadIM(p *parser) (insertionMode, bool) {
var (
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
}
return afterHeadIM, !implied
}
- return inHeadIM, !implied
+ return inHeadIM, true
}
// Section 11.2.5.4.6.
}
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)
}
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)
p.afe.remove(formattingElement)
return
}
+ if !p.elementInScope(defaultScopeStopTags, tag) {
+ // Ignore the tag.
+ return
+ }
// Steps 5-6. Find the furthest block.
var furthestBlock *Node
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)
// 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
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":
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 {
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))
}
}
}
+
+// 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,
+}
// 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)
}
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())
}
}
}
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
}
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 {
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)
}
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)
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)
}
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)
// 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
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()))
}
// 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.
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
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.
// 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
}
}
-func noSpace(c int) int {
+func noSpace(c rune) rune {
if isSpace(c) {
return -1
}
"PSlice": null,
"PSliceP": null,
"EmptySlice": [],
- "NilSlice": [],
+ "NilSlice": null,
"StringSlice": [
"str24",
"str25",
},
"EmptyMap": null,
"NilMap": null,
- "Slice": [],
- "SliceP": [],
+ "Slice": null,
+ "SliceP": null,
"PSlice": [
{
"Tag": "tag20"
"Tag": "tag23"
}
],
- "EmptySlice": [],
- "NilSlice": [],
- "StringSlice": [],
- "ByteSlice": "",
+ "EmptySlice": null,
+ "NilSlice": null,
+ "StringSlice": null,
+ "ByteSlice": null,
"Small": {
"Tag": ""
},
}
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)
var optionalsExpected = `{
"sr": "",
"omitempty": 0,
- "slr": [],
+ "slr": null,
"mr": {}
}`
}
}
-func isSpace(c int) bool {
+func isSpace(c rune) bool {
return c == ' ' || c == '\t' || c == '\r' || c == '\n'
}
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)
}
func nonSpace(b []byte) bool {
for _, c := range b {
- if !isSpace(int(c)) {
+ if !isSpace(rune(c)) {
return true
}
}
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":
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])
}
}
}
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])
}
}
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])
}
}
-// 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.
/*
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
+}
// 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
}
// 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
}
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
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
}
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))
// LookupTXT returns the DNS TXT records for the given domain name.
func LookupTXT(name string) (txt []string, err os.Error) {
- return nil, os.NewError("net.LookupTXT is not implemente