From: Rob Pike Date: Mon, 11 Jun 2012 21:52:09 +0000 (-0400) Subject: fmt.Fscanf: don't read past newline X-Git-Tag: go1.1rc2~2945 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=2a0fdf6ea05dc31526e95990aadc2b327933cce1;p=gostls13.git fmt.Fscanf: don't read past newline Makes interactive uses work line-by-line. Fixes #3481. R=golang-dev, bradfitz, r CC=golang-dev https://golang.org/cl/6297075 --- diff --git a/src/pkg/fmt/scan.go b/src/pkg/fmt/scan.go index 0b3e04069a..d69911c7d7 100644 --- a/src/pkg/fmt/scan.go +++ b/src/pkg/fmt/scan.go @@ -1090,7 +1090,8 @@ 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 || inputc == '\n' { + // If we've reached a newline, stop now; don't read ahead. return } if !isSpace(inputc) { diff --git a/src/pkg/fmt/scan_test.go b/src/pkg/fmt/scan_test.go index 320857b73e..cc09e910aa 100644 --- a/src/pkg/fmt/scan_test.go +++ b/src/pkg/fmt/scan_test.go @@ -810,6 +810,33 @@ func TestMultiLine(t *testing.T) { } } +// simpleReader is a strings.Reader that implements only Read, not ReadRune. +// Good for testing readahead. +type simpleReader struct { + sr *strings.Reader +} + +func (s *simpleReader) Read(b []byte) (n int, err error) { + return s.sr.Read(b) +} + +// Test that Fscanf does not read past newline. Issue 3481. +func TestLineByLineFscanf(t *testing.T) { + r := &simpleReader{strings.NewReader("1\n2\n")} + var i, j int + n, err := Fscanf(r, "%v\n", &i) + if n != 1 || err != nil { + t.Fatalf("first read: %d %q", n, err) + } + n, err = Fscanf(r, "%v\n", &j) + if n != 1 || err != nil { + t.Fatalf("second read: %d %q", n, err) + } + if i != 1 || j != 2 { + t.Errorf("wrong values; wanted 1 2 got %d %d", i, j) + } +} + // RecursiveInt accepts a string matching %d.%d.%d.... // and parses it into a linked list. // It allows us to benchmark recursive descent style scanners.