cue/errors: refactor position computation

Issue #52.

Change-Id: Ie4f42dc39bd317eef8bc64052ff51cdbbfe411cc
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2177
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cue/errors/errors.go b/cue/errors/errors.go
index f1b1e70..ad98138 100644
--- a/cue/errors/errors.go
+++ b/cue/errors/errors.go
@@ -250,30 +250,32 @@
 func Print(w io.Writer, err error) {
 	if list, ok := err.(List); ok {
 		for _, e := range list {
-			printErrors(w, e)
+			printError(w, e)
 		}
 	} else if err != nil {
-		printErrors(w, err)
-	}
-}
-
-func printErrors(w io.Writer, err error) {
-	for ; err != nil; err = xerrors.Unwrap(err) {
 		printError(w, err)
 	}
 }
 
 func printError(w io.Writer, err error) {
+	if err == nil {
+		return
+	}
+
 	positions := []string{}
-	switch x := err.(type) {
-	case interface{ Position() token.Position }:
-		if pos := x.Position().String(); pos != "-" {
-			positions = append(positions, pos)
-		}
-	case interface{ Positions() []token.Pos }:
-		for _, p := range x.Positions() {
-			if p.IsValid() {
-				positions = append(positions, p.String())
+
+	for e := err; e != nil; e = xerrors.Unwrap(e) {
+		switch x := e.(type) {
+		case interface{ Position() token.Position }:
+			if pos := x.Position().String(); pos != "-" {
+				positions = append(positions, pos)
+			}
+
+		case interface{ Positions() []token.Pos }:
+			for _, p := range x.Positions() {
+				if p.IsValid() {
+					positions = append(positions, p.String())
+				}
 			}
 		}
 	}
@@ -285,9 +287,8 @@
 
 	unique.Strings(&positions)
 
-	fmt.Fprintf(w, "%v:", err)
+	fmt.Fprintf(w, "%v:\n", err)
 	for _, pos := range positions {
-		fmt.Fprintf(w, "\n    %v", pos)
+		fmt.Fprintf(w, "    %v\n", pos)
 	}
-	fmt.Fprintln(w)
 }