aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/fmt
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2011-03-24 23:46:17 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2011-03-24 23:46:17 +0000
commit8039ca76a5705ae5052b20cee64110c32545c4fc (patch)
tree9319bca77115a32f6a0b5e8bcd651465b14c76da /libgo/go/fmt
parent7114321ee4f521ea9fbdd08a4c23b361181f3658 (diff)
downloadgcc-8039ca76a5705ae5052b20cee64110c32545c4fc.zip
gcc-8039ca76a5705ae5052b20cee64110c32545c4fc.tar.gz
gcc-8039ca76a5705ae5052b20cee64110c32545c4fc.tar.bz2
Update to current version of Go library.
From-SVN: r171427
Diffstat (limited to 'libgo/go/fmt')
-rw-r--r--libgo/go/fmt/format.go4
-rw-r--r--libgo/go/fmt/scan.go61
-rw-r--r--libgo/go/fmt/scan_test.go29
3 files changed, 52 insertions, 42 deletions
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)
}
}