2013-10-18 11:38:30 +08:00
|
|
|
package util
|
2013-10-17 10:21:35 +08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
2014-01-16 09:24:14 +08:00
|
|
|
"fmt"
|
2013-10-17 10:21:35 +08:00
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2013-10-18 11:38:30 +08:00
|
|
|
type ContextualError struct {
|
2015-01-21 03:22:20 +08:00
|
|
|
srcname string
|
|
|
|
title string
|
|
|
|
line string
|
|
|
|
lineno int
|
|
|
|
colno int
|
|
|
|
msg string
|
2013-10-17 10:21:35 +08:00
|
|
|
}
|
|
|
|
|
2015-01-21 03:22:20 +08:00
|
|
|
func NewContextualError(srcname, title, text string, pos int, format string, args ...interface{}) *ContextualError {
|
2013-10-18 11:38:30 +08:00
|
|
|
lineno, colno, line := FindContext(text, pos)
|
2015-01-21 03:22:20 +08:00
|
|
|
return &ContextualError{srcname, title, line, lineno, colno, fmt.Sprintf(format, args...)}
|
2013-10-18 11:38:30 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *ContextualError) Error() string {
|
2015-01-21 03:22:20 +08:00
|
|
|
return fmt.Sprintf("%s:%d:%d %s:%s", e.srcname, e.lineno, e.colno, e.title, e.msg)
|
2013-10-17 10:21:35 +08:00
|
|
|
}
|
|
|
|
|
2013-10-18 11:38:30 +08:00
|
|
|
func (e *ContextualError) Pprint() string {
|
2013-10-17 10:21:35 +08:00
|
|
|
buf := new(bytes.Buffer)
|
|
|
|
// Position info
|
2015-01-21 03:22:20 +08:00
|
|
|
fmt.Fprintf(buf, "\033[1m%s:%d:%d: ", e.srcname, e.lineno+1, e.colno+1)
|
2013-10-17 10:21:35 +08:00
|
|
|
// "error:"
|
2015-01-21 03:22:20 +08:00
|
|
|
fmt.Fprintf(buf, "\033[31m%s: ", e.title)
|
2013-10-17 10:21:35 +08:00
|
|
|
// Message
|
|
|
|
fmt.Fprintf(buf, "\033[m\033[1m%s\033[m\n", e.msg)
|
|
|
|
// Context: line
|
|
|
|
// TODO Handle long lines
|
|
|
|
fmt.Fprintf(buf, "%s\n", e.line)
|
|
|
|
// Context: arrow
|
|
|
|
// TODO Handle multi-width characters
|
|
|
|
fmt.Fprintf(buf, "%s\033[32;1m^\033[m\n", strings.Repeat(" ", e.colno))
|
|
|
|
return buf.String()
|
|
|
|
}
|