go/printer: avoid stomping on err before checking it
Change-Id: I97ba31e758d3396842ad99a08af696e49a5f1a7d
Reviewed-on: https://go-review.googlesource.com/13954
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
diff --git a/src/go/printer/printer.go b/src/go/printer/printer.go
index f9343d3..a3eaa66 100644
--- a/src/go/printer/printer.go
+++ b/src/go/printer/printer.go
@@ -1178,7 +1178,9 @@
case '\n', '\f':
_, err = p.output.Write(data[m:n])
p.resetSpace()
- _, err = p.output.Write(aNewline)
+ if err == nil {
+ _, err = p.output.Write(aNewline)
+ }
case tabwriter.Escape:
_, err = p.output.Write(data[m:n])
p.state = inEscape
diff --git a/src/go/printer/printer_test.go b/src/go/printer/printer_test.go
index 3b0570e..73f9ead 100644
--- a/src/go/printer/printer_test.go
+++ b/src/go/printer/printer_test.go
@@ -12,6 +12,7 @@
"go/ast"
"go/parser"
"go/token"
+ "io"
"io/ioutil"
"path/filepath"
"testing"
@@ -548,6 +549,46 @@
}
}
+type limitWriter struct {
+ remaining int
+ errCount int
+}
+
+func (l *limitWriter) Write(buf []byte) (n int, err error) {
+ n = len(buf)
+ if n >= l.remaining {
+ n = l.remaining
+ err = io.EOF
+ l.errCount++
+ }
+ l.remaining -= n
+ return n, err
+}
+
+// Test whether the printer stops writing after the first error
+func TestWriteErrors(t *testing.T) {
+ const filename = "printer.go"
+ src, err := ioutil.ReadFile(filename)
+ if err != nil {
+ panic(err) // error in test
+ }
+ file, err := parser.ParseFile(fset, filename, src, 0)
+ if err != nil {
+ panic(err) // error in test
+ }
+ for i := 0; i < 20; i++ {
+ lw := &limitWriter{remaining: i}
+ err := (&Config{Mode: RawFormat}).Fprint(lw, fset, file)
+ if lw.errCount > 1 {
+ t.Fatal("Writes continued after first error returned")
+ }
+ // We expect errCount be 1 iff err is set
+ if (lw.errCount != 0) != (err != nil) {
+ t.Fatal("Expected err when errCount != 0")
+ }
+ }
+}
+
// TextX is a skeleton test that can be filled in for debugging one-off cases.
// Do not remove.
func TestX(t *testing.T) {