From 8039ca76a5705ae5052b20cee64110c32545c4fc Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 24 Mar 2011 23:46:17 +0000 Subject: Update to current version of Go library. From-SVN: r171427 --- libgo/go/fmt/format.go | 4 ++-- libgo/go/fmt/scan.go | 61 ++++++++++++++++++++++++++++++----------------- libgo/go/fmt/scan_test.go | 29 +++++++++------------- 3 files changed, 52 insertions(+), 42 deletions(-) (limited to 'libgo/go/fmt') diff --git a/libgo/go/fmt/format.go b/libgo/go/fmt/format.go index 86057bf..caaa7ac 100644 --- a/libgo/go/fmt/format.go +++ b/libgo/go/fmt/format.go @@ -107,7 +107,7 @@ func (f *fmt) writePadding(n int, padding []byte) { } // Append b to f.buf, padded on left (w > 0) or right (w < 0 or f.minus) -// clear flags aftewards. +// clear flags afterwards. func (f *fmt) pad(b []byte) { var padding []byte var left, right int @@ -124,7 +124,7 @@ func (f *fmt) pad(b []byte) { } // append s to buf, padded on left (w > 0) or right (w < 0 or f.minus). -// clear flags aftewards. +// clear flags afterwards. func (f *fmt) padString(s string) { var padding []byte var left, right int diff --git a/libgo/go/fmt/scan.go b/libgo/go/fmt/scan.go index c0f2bac..36271a8 100644 --- a/libgo/go/fmt/scan.go +++ b/libgo/go/fmt/scan.go @@ -35,10 +35,15 @@ type ScanState interface { ReadRune() (rune int, size int, err os.Error) // UnreadRune causes the next call to ReadRune to return the same rune. UnreadRune() os.Error - // Token returns the next space-delimited token from the input. If - // a width has been specified, the returned token will be no longer - // than the width. - Token() (token string, err os.Error) + // Token skips space in the input if skipSpace is true, then returns the + // run of Unicode code points c satisfying f(c). If f is nil, + // !unicode.IsSpace(c) is used; that is, the token will hold non-space + // characters. Newlines are treated as space unless the scan operation + // is Scanln, Fscanln or Sscanln, in which case a newline is treated as + // 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) // 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) @@ -134,7 +139,7 @@ type scanError struct { err os.Error } -const EOF = -1 +const eof = -1 // ss is the internal implementation of ScanState. type ss struct { @@ -202,7 +207,7 @@ func (s *ss) getRune() (rune int) { rune, _, err := s.ReadRune() if err != nil { if err == os.EOF { - return EOF + return eof } s.error(err) } @@ -214,7 +219,7 @@ func (s *ss) getRune() (rune int) { // syntax error. func (s *ss) mustReadRune() (rune int) { rune = s.getRune() - if rune == EOF { + if rune == eof { s.error(io.ErrUnexpectedEOF) } return @@ -238,7 +243,7 @@ func (s *ss) errorString(err string) { panic(scanError{os.ErrorString(err)}) } -func (s *ss) Token() (tok string, err os.Error) { +func (s *ss) Token(skipSpace bool, f func(int) bool) (tok []byte, err os.Error) { defer func() { if e := recover(); e != nil { if se, ok := e.(scanError); ok { @@ -248,10 +253,19 @@ func (s *ss) Token() (tok string, err os.Error) { } } }() - tok = s.token() + if f == nil { + f = notSpace + } + s.buf.Reset() + tok = s.token(skipSpace, f) return } +// notSpace is the default scanning function used in Token. +func notSpace(r int) bool { + return !unicode.IsSpace(r) +} + // readRune is a structure to enable reading UTF-8 encoded code points // from an io.Reader. It is used if the Reader given to the scanner does // not already implement io.RuneReader. @@ -364,7 +378,7 @@ func (s *ss) free(old ssave) { func (s *ss) skipSpace(stopAtNewline bool) { for { rune := s.getRune() - if rune == EOF { + if rune == eof { return } if rune == '\n' { @@ -384,24 +398,27 @@ func (s *ss) skipSpace(stopAtNewline bool) { } } + // token returns the next space-delimited string from the input. It // skips white space. For Scanln, it stops at newlines. For Scan, // newlines are treated as spaces. -func (s *ss) token() string { - s.skipSpace(false) +func (s *ss) token(skipSpace bool, f func(int) bool) []byte { + if skipSpace { + s.skipSpace(false) + } // read until white space or newline for { rune := s.getRune() - if rune == EOF { + if rune == eof { break } - if unicode.IsSpace(rune) { + if !f(rune) { s.UnreadRune() break } s.buf.WriteRune(rune) } - return s.buf.String() + return s.buf.Bytes() } // typeError indicates that the type of the operand did not match the format @@ -416,7 +433,7 @@ var boolError = os.ErrorString("syntax error scanning boolean") // 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 { + if rune == eof { return false } if strings.IndexRune(ok, rune) >= 0 { @@ -425,7 +442,7 @@ func (s *ss) consume(ok string, accept bool) bool { } return true } - if rune != EOF && accept { + if rune != eof && accept { s.UnreadRune() } return false @@ -434,7 +451,7 @@ func (s *ss) consume(ok string, accept bool) bool { // peek reports whether the next character is in the ok string, without consuming it. func (s *ss) peek(ok string) bool { rune := s.getRune() - if rune != EOF { + if rune != eof { s.UnreadRune() } return strings.IndexRune(ok, rune) >= 0 @@ -729,7 +746,7 @@ func (s *ss) convertString(verb int) (str string) { case 'x': str = s.hexString() default: - str = s.token() // %s and %v just return the next word + str = string(s.token(true, notSpace)) // %s and %v just return the next word } // Empty strings other than with %q are not OK. if len(str) == 0 && verb != 'q' && s.maxWid > 0 { @@ -797,7 +814,7 @@ func (s *ss) hexDigit(digit int) int { // There must be either two hexadecimal digits or a space character in the input. func (s *ss) hexByte() (b byte, ok bool) { rune1 := s.getRune() - if rune1 == EOF { + if rune1 == eof { return } if unicode.IsSpace(rune1) { @@ -953,7 +970,7 @@ func (s *ss) doScan(a []interface{}) (numProcessed int, err os.Error) { if !s.nlIsSpace { for { rune := s.getRune() - if rune == '\n' || rune == EOF { + if rune == '\n' || rune == eof { break } if !unicode.IsSpace(rune) { @@ -993,7 +1010,7 @@ func (s *ss) advance(format string) (i int) { // There was space in the format, so there should be space (EOF) // in the input. inputc := s.getRune() - if inputc == EOF { + if inputc == eof { return } if !unicode.IsSpace(inputc) { diff --git a/libgo/go/fmt/scan_test.go b/libgo/go/fmt/scan_test.go index 65adb02..8d2e6f5 100644 --- a/libgo/go/fmt/scan_test.go +++ b/libgo/go/fmt/scan_test.go @@ -88,14 +88,15 @@ type FloatTest struct { type Xs string func (x *Xs) Scan(state ScanState, verb int) os.Error { - tok, err := state.Token() + tok, err := state.Token(true, func(r int) bool { return r == verb }) if err != nil { return err } - if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(tok) { + s := string(tok) + if !regexp.MustCompile("^" + string(verb) + "+$").MatchString(s) { return os.ErrorString("syntax error for xs") } - *x = Xs(tok) + *x = Xs(s) return nil } @@ -113,9 +114,11 @@ func (s *IntString) Scan(state ScanState, verb int) os.Error { return err } - if _, err := Fscan(state, &s.s); err != nil { + tok, err := state.Token(true, nil) + if err != nil { return err } + s.s = string(tok) return nil } @@ -331,7 +334,7 @@ var multiTests = []ScanfMultiTest{ {"%c%c%c", "2\u50c2X", args(&i, &j, &k), args('2', '\u50c2', 'X'), ""}, // Custom scanners. - {"%2e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""}, + {"%e%f", "eefffff", args(&x, &y), args(Xs("ee"), Xs("fffff")), ""}, {"%4v%s", "12abcd", args(&z, &s), args(IntString{12, "ab"}, "cd"), ""}, // Errors @@ -476,22 +479,12 @@ func verifyInf(str string, t *testing.T) { } } - func TestInf(t *testing.T) { for _, s := range []string{"inf", "+inf", "-inf", "INF", "-INF", "+INF", "Inf", "-Inf", "+Inf"} { verifyInf(s, t) } } -// TODO: there's no conversion from []T to ...T, but we can fake it. These -// functions do the faking. We index the table by the length of the param list. -var fscanf = []func(io.Reader, string, []interface{}) (int, os.Error){ - 0: func(r io.Reader, f string, i []interface{}) (int, os.Error) { return Fscanf(r, f) }, - 1: func(r io.Reader, f string, i []interface{}) (int, os.Error) { return Fscanf(r, f, i[0]) }, - 2: func(r io.Reader, f string, i []interface{}) (int, os.Error) { return Fscanf(r, f, i[0], i[1]) }, - 3: func(r io.Reader, f string, i []interface{}) (int, os.Error) { return Fscanf(r, f, i[0], i[1], i[2]) }, -} - func testScanfMulti(name string, t *testing.T) { sliceType := reflect.Typeof(make([]interface{}, 1)).(*reflect.SliceType) for _, test := range multiTests { @@ -501,7 +494,7 @@ func testScanfMulti(name string, t *testing.T) { } else { r = newReader(test.text) } - n, err := fscanf[len(test.in)](r, test.format, test.in) + n, err := Fscanf(r, test.format, test.in...) if err != nil { if test.err == "" { t.Errorf("got error scanning (%q, %q): %q", test.format, test.text, err) @@ -830,12 +823,12 @@ func testScanInts(t *testing.T, scan func(*RecursiveInt, *bytes.Buffer) os.Error i := 1 for ; r != nil; r = r.next { if r.i != i { - t.Fatal("bad scan: expected %d got %d", i, r.i) + t.Fatalf("bad scan: expected %d got %d", i, r.i) } i++ } if i-1 != intCount { - t.Fatal("bad scan count: expected %d got %d", intCount, i-1) + t.Fatalf("bad scan count: expected %d got %d", intCount, i-1) } } -- cgit v1.1