Update libcni to 0.7.0 (Spec ver 0.4.0)

This commit is contained in:
Tomofumi Hayashi
2019-05-15 17:06:26 +09:00
committed by Tomofumi Hayashi
parent 6c23cad08d
commit e723aabca8
169 changed files with 12524 additions and 1453 deletions

View File

@@ -1,10 +1,11 @@
language: go
go_import_path: github.com/pkg/errors
go:
- 1.9.x
- 1.10.x
- 1.11.x
- 1.4.3
- 1.5.4
- 1.6.2
- 1.7.1
- tip
script:
- make check
- go test -v ./...

View File

@@ -1,44 +0,0 @@
PKGS := github.com/pkg/errors
SRCDIRS := $(shell go list -f '{{.Dir}}' $(PKGS))
GO := go
check: test vet gofmt misspell unconvert staticcheck ineffassign unparam
test:
$(GO) test $(PKGS)
vet: | test
$(GO) vet $(PKGS)
staticcheck:
$(GO) get honnef.co/go/tools/cmd/staticcheck
staticcheck -checks all $(PKGS)
misspell:
$(GO) get github.com/client9/misspell/cmd/misspell
misspell \
-locale GB \
-error \
*.md *.go
unconvert:
$(GO) get github.com/mdempsky/unconvert
unconvert -v $(PKGS)
ineffassign:
$(GO) get github.com/gordonklaus/ineffassign
find $(SRCDIRS) -name '*.go' | xargs ineffassign
pedantic: check errcheck
unparam:
$(GO) get mvdan.cc/unparam
unparam ./...
errcheck:
$(GO) get github.com/kisielk/errcheck
errcheck $(PKGS)
gofmt:
@echo Checking code is gofmted
@test -z "$(shell gofmt -s -l -d -e $(SRCDIRS) | tee /dev/stderr)"

View File

@@ -1,4 +1,4 @@
# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors) [![Sourcegraph](https://sourcegraph.com/github.com/pkg/errors/-/badge.svg)](https://sourcegraph.com/github.com/pkg/errors?badge)
# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors)
Package errors provides simple error handling primitives.
@@ -41,19 +41,12 @@ default:
[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).
## Roadmap
With the upcoming [Go2 error proposals](https://go.googlesource.com/proposal/+/master/design/go2draft.md) this package is moving into maintenance mode. The roadmap for a 1.0 release is as follows:
- 0.9. Remove pre Go 1.9 support, address outstanding pull requests (if possible)
- 1.0. Final release.
## Contributing
Because of the Go2 errors changes, this package is not accepting proposals for new functionality. With that said, we welcome pull requests, bug fixes and issue reports.
We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high.
Before sending a PR, please discuss your change by raising an issue.
Before proposing a change, please discuss your change by raising an issue.
## License
## Licence
BSD-2-Clause

View File

@@ -15,7 +15,6 @@ func noErrors(at, depth int) error {
}
return noErrors(at+1, depth)
}
func yesErrors(at, depth int) error {
if at >= depth {
return New("ye error")
@@ -23,11 +22,8 @@ func yesErrors(at, depth int) error {
return yesErrors(at+1, depth)
}
// GlobalE is an exported global to store the result of benchmark results,
// preventing the compiler from optimising the benchmark functions away.
var GlobalE interface{}
func BenchmarkErrors(b *testing.B) {
var toperr error
type run struct {
stack int
std bool
@@ -57,54 +53,7 @@ func BenchmarkErrors(b *testing.B) {
err = f(0, r.stack)
}
b.StopTimer()
GlobalE = err
toperr = err
})
}
}
func BenchmarkStackFormatting(b *testing.B) {
type run struct {
stack int
format string
}
runs := []run{
{10, "%s"},
{10, "%v"},
{10, "%+v"},
{30, "%s"},
{30, "%v"},
{30, "%+v"},
{60, "%s"},
{60, "%v"},
{60, "%+v"},
}
var stackStr string
for _, r := range runs {
name := fmt.Sprintf("%s-stack-%d", r.format, r.stack)
b.Run(name, func(b *testing.B) {
err := yesErrors(0, r.stack)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
stackStr = fmt.Sprintf(r.format, err)
}
b.StopTimer()
})
}
for _, r := range runs {
name := fmt.Sprintf("%s-stacktrace-%d", r.format, r.stack)
b.Run(name, func(b *testing.B) {
err := yesErrors(0, r.stack)
st := err.(*fundamental).stack.StackTrace()
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
stackStr = fmt.Sprintf(r.format, st)
}
b.StopTimer()
})
}
GlobalE = stackStr
}

View File

@@ -6,7 +6,7 @@
// return err
// }
//
// which when applied recursively up the call stack results in error reports
// which applied recursively up the call stack results in error reports
// without context or debugging information. The errors package allows
// programmers to add context to the failure path in their code in a way
// that does not destroy the original value of the error.
@@ -15,17 +15,16 @@
//
// The errors.Wrap function returns a new error that adds context to the
// original error by recording a stack trace at the point Wrap is called,
// together with the supplied message. For example
// and the supplied message. For example
//
// _, err := ioutil.ReadAll(r)
// if err != nil {
// return errors.Wrap(err, "read failed")
// }
//
// If additional control is required, the errors.WithStack and
// errors.WithMessage functions destructure errors.Wrap into its component
// operations: annotating an error with a stack trace and with a message,
// respectively.
// If additional control is required the errors.WithStack and errors.WithMessage
// functions destructure errors.Wrap into its component operations of annotating
// an error with a stack trace and an a message, respectively.
//
// Retrieving the cause of an error
//
@@ -39,7 +38,7 @@
// }
//
// can be inspected by errors.Cause. errors.Cause will recursively retrieve
// the topmost error that does not implement causer, which is assumed to be
// the topmost error which does not implement causer, which is assumed to be
// the original cause. For example:
//
// switch err := errors.Cause(err).(type) {
@@ -49,16 +48,16 @@
// // unknown error
// }
//
// Although the causer interface is not exported by this package, it is
// considered a part of its stable public interface.
// causer interface is not exported by this package, but is considered a part
// of stable public API.
//
// Formatted printing of errors
//
// All error values returned from this package implement fmt.Formatter and can
// be formatted by the fmt package. The following verbs are supported:
// be formatted by the fmt package. The following verbs are supported
//
// %s print the error. If the error has a Cause it will be
// printed recursively.
// printed recursively
// %v see %s
// %+v extended format. Each Frame of the error's StackTrace will
// be printed in detail.
@@ -66,13 +65,13 @@
// Retrieving the stack trace of an error or wrapper
//
// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
// invoked. This information can be retrieved with the following interface:
// invoked. This information can be retrieved with the following interface.
//
// type stackTracer interface {
// StackTrace() errors.StackTrace
// }
//
// The returned errors.StackTrace type is defined as
// Where errors.StackTrace is defined as
//
// type StackTrace []Frame
//
@@ -82,12 +81,12 @@
//
// if err, ok := err.(stackTracer); ok {
// for _, f := range err.StackTrace() {
// fmt.Printf("%+s:%d\n", f, f)
// fmt.Printf("%+s:%d", f)
// }
// }
//
// Although the stackTracer interface is not exported by this package, it is
// considered a part of its stable public interface.
// stackTracer interface is not exported by this package, but is considered a part
// of stable public API.
//
// See the documentation for Frame.Format for more details.
package errors
@@ -193,7 +192,7 @@ func Wrap(err error, message string) error {
}
// Wrapf returns an error annotating err with a stack trace
// at the point Wrapf is called, and the format specifier.
// at the point Wrapf is call, and the format specifier.
// If err is nil, Wrapf returns nil.
func Wrapf(err error, format string, args ...interface{}) error {
if err == nil {
@@ -221,18 +220,6 @@ func WithMessage(err error, message string) error {
}
}
// WithMessagef annotates err with the format specifier.
// If err is nil, WithMessagef returns nil.
func WithMessagef(err error, format string, args ...interface{}) error {
if err == nil {
return nil
}
return &withMessage{
cause: err,
msg: fmt.Sprintf(format, args...),
}
}
type withMessage struct {
cause error
msg string

View File

@@ -196,32 +196,7 @@ func TestWithMessage(t *testing.T) {
t.Errorf("WithMessage(%v, %q): got: %q, want %q", tt.err, tt.message, got, tt.want)
}
}
}
func TestWithMessagefNil(t *testing.T) {
got := WithMessagef(nil, "no error")
if got != nil {
t.Errorf("WithMessage(nil, \"no error\"): got %#v, expected nil", got)
}
}
func TestWithMessagef(t *testing.T) {
tests := []struct {
err error
message string
want string
}{
{io.EOF, "read error", "read error: EOF"},
{WithMessagef(io.EOF, "read error without format specifier"), "client error", "client error: read error without format specifier: EOF"},
{WithMessagef(io.EOF, "read error with %d format specifier", 1), "client error", "client error: read error with 1 format specifier: EOF"},
}
for _, tt := range tests {
got := WithMessagef(tt.err, tt.message).Error()
if got != tt.want {
t.Errorf("WithMessage(%v, %q): got: %q, want %q", tt.err, tt.message, got, tt.want)
}
}
}
// errors.New, etc values are not expected to be compared by value

View File

@@ -360,32 +360,7 @@ func TestFormatGeneric(t *testing.T) {
}
}
func wrappedNew(message string) error { // This function will be mid-stack inlined in go 1.12+
return New(message)
}
func TestFormatWrappedNew(t *testing.T) {
tests := []struct {
error
format string
want string
}{{
wrappedNew("error"),
"%+v",
"error\n" +
"github.com/pkg/errors.wrappedNew\n" +
"\t.+/github.com/pkg/errors/format_test.go:364\n" +
"github.com/pkg/errors.TestFormatWrappedNew\n" +
"\t.+/github.com/pkg/errors/format_test.go:373",
}}
for i, tt := range tests {
testFormatRegexp(t, i, tt.error, tt.format, tt.want)
}
}
func testFormatRegexp(t *testing.T, n int, arg interface{}, format, want string) {
t.Helper()
got := fmt.Sprintf(format, arg)
gotLines := strings.SplitN(got, "\n", -1)
wantLines := strings.SplitN(want, "\n", -1)
@@ -516,7 +491,7 @@ type wrapper struct {
want []string
}
func prettyBlocks(blocks []string) string {
func prettyBlocks(blocks []string, prefix ...string) string {
var out []string
for _, b := range blocks {

View File

@@ -5,13 +5,10 @@ import (
"io"
"path"
"runtime"
"strconv"
"strings"
)
// Frame represents a program counter inside a stack frame.
// For historical reasons if Frame is interpreted as a uintptr
// its value represents the program counter + 1.
type Frame uintptr
// pc returns the program counter for this frame;
@@ -40,15 +37,6 @@ func (f Frame) line() int {
return line
}
// name returns the name of this function, if known.
func (f Frame) name() string {
fn := runtime.FuncForPC(f.pc())
if fn == nil {
return "unknown"
}
return fn.Name()
}
// Format formats the frame according to the fmt.Formatter interface.
//
// %s source file
@@ -58,24 +46,29 @@ func (f Frame) name() string {
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+s function name and path of source file relative to the compile time
// GOPATH separated by \n\t (<funcname>\n\t<path>)
// %+s path of source file relative to the compile time GOPATH
// %+v equivalent to %+s:%d
func (f Frame) Format(s fmt.State, verb rune) {
switch verb {
case 's':
switch {
case s.Flag('+'):
io.WriteString(s, f.name())
io.WriteString(s, "\n\t")
io.WriteString(s, f.file())
pc := f.pc()
fn := runtime.FuncForPC(pc)
if fn == nil {
io.WriteString(s, "unknown")
} else {
file, _ := fn.FileLine(pc)
fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
}
default:
io.WriteString(s, path.Base(f.file()))
}
case 'd':
io.WriteString(s, strconv.Itoa(f.line()))
fmt.Fprintf(s, "%d", f.line())
case 'n':
io.WriteString(s, funcname(f.name()))
name := runtime.FuncForPC(f.pc()).Name()
io.WriteString(s, funcname(name))
case 'v':
f.Format(s, 's')
io.WriteString(s, ":")
@@ -86,46 +79,24 @@ func (f Frame) Format(s fmt.State, verb rune) {
// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
type StackTrace []Frame
// Format formats the stack of Frames according to the fmt.Formatter interface.
//
// %s lists source files for each Frame in the stack
// %v lists the source file and line number for each Frame in the stack
//
// Format accepts flags that alter the printing of some verbs, as follows:
//
// %+v Prints filename, function, and line number for each Frame in the stack.
func (st StackTrace) Format(s fmt.State, verb rune) {
switch verb {
case 'v':
switch {
case s.Flag('+'):
for _, f := range st {
io.WriteString(s, "\n")
f.Format(s, verb)
fmt.Fprintf(s, "\n%+v", f)
}
case s.Flag('#'):
fmt.Fprintf(s, "%#v", []Frame(st))
default:
st.formatSlice(s, verb)
fmt.Fprintf(s, "%v", []Frame(st))
}
case 's':
st.formatSlice(s, verb)
fmt.Fprintf(s, "%s", []Frame(st))
}
}
// formatSlice will format this StackTrace into the given buffer as a slice of
// Frame, only valid when called with '%s' or '%v'.
func (st StackTrace) formatSlice(s fmt.State, verb rune) {
io.WriteString(s, "[")
for i, f := range st {
if i > 0 {
io.WriteString(s, " ")
}
f.Format(s, verb)
}
io.WriteString(s, "]")
}
// stack represents a stack of program counters.
type stack []uintptr
@@ -165,3 +136,43 @@ func funcname(name string) string {
i = strings.Index(name, ".")
return name[i+1:]
}
func trimGOPATH(name, file string) string {
// Here we want to get the source file path relative to the compile time
// GOPATH. As of Go 1.6.x there is no direct way to know the compiled
// GOPATH at runtime, but we can infer the number of path segments in the
// GOPATH. We note that fn.Name() returns the function name qualified by
// the import path, which does not include the GOPATH. Thus we can trim
// segments from the beginning of the file path until the number of path
// separators remaining is one more than the number of path separators in
// the function name. For example, given:
//
// GOPATH /home/user
// file /home/user/src/pkg/sub/file.go
// fn.Name() pkg/sub.Type.Method
//
// We want to produce:
//
// pkg/sub/file.go
//
// From this we can easily see that fn.Name() has one less path separator
// than our desired output. We count separators from the end of the file
// path until it finds two more than in the function name and then move
// one character forward to preserve the initial path segment without a
// leading separator.
const sep = "/"
goal := strings.Count(name, sep) + 2
i := len(file)
for n := 0; n < goal; n++ {
i = strings.LastIndex(file[:i], sep)
if i == -1 {
// not enough separators found, set i so that the slice expression
// below leaves file unmodified
i = -len(sep)
break
}
}
// get back to 0 or trim the leading separator
file = file[i+len(sep):]
return file
}

View File

@@ -6,18 +6,51 @@ import (
"testing"
)
var initpc = caller()
var initpc, _, _, _ = runtime.Caller(0)
func TestFrameLine(t *testing.T) {
var tests = []struct {
Frame
want int
}{{
Frame(initpc),
9,
}, {
func() Frame {
var pc, _, _, _ = runtime.Caller(0)
return Frame(pc)
}(),
20,
}, {
func() Frame {
var pc, _, _, _ = runtime.Caller(1)
return Frame(pc)
}(),
28,
}, {
Frame(0), // invalid PC
0,
}}
for _, tt := range tests {
got := tt.Frame.line()
want := tt.want
if want != got {
t.Errorf("Frame(%v): want: %v, got: %v", uintptr(tt.Frame), want, got)
}
}
}
type X struct{}
// val returns a Frame pointing to itself.
func (x X) val() Frame {
return caller()
var pc, _, _, _ = runtime.Caller(0)
return Frame(pc)
}
// ptr returns a Frame pointing to itself.
func (x *X) ptr() Frame {
return caller()
var pc, _, _, _ = runtime.Caller(0)
return Frame(pc)
}
func TestFrameFormat(t *testing.T) {
@@ -26,32 +59,32 @@ func TestFrameFormat(t *testing.T) {
format string
want string
}{{
initpc,
Frame(initpc),
"%s",
"stack_test.go",
}, {
initpc,
Frame(initpc),
"%+s",
"github.com/pkg/errors.init\n" +
"\t.+/github.com/pkg/errors/stack_test.go",
}, {
0,
Frame(0),
"%s",
"unknown",
}, {
0,
Frame(0),
"%+s",
"unknown",
}, {
initpc,
Frame(initpc),
"%d",
"9",
}, {
0,
Frame(0),
"%d",
"0",
}, {
initpc,
Frame(initpc),
"%n",
"init",
}, {
@@ -69,20 +102,20 @@ func TestFrameFormat(t *testing.T) {
"%n",
"X.val",
}, {
0,
Frame(0),
"%n",
"",
}, {
initpc,
Frame(initpc),
"%v",
"stack_test.go:9",
}, {
initpc,
Frame(initpc),
"%+v",
"github.com/pkg/errors.init\n" +
"\t.+/github.com/pkg/errors/stack_test.go:9",
}, {
0,
Frame(0),
"%v",
"unknown:0",
}}
@@ -113,6 +146,24 @@ func TestFuncname(t *testing.T) {
}
}
func TestTrimGOPATH(t *testing.T) {
var tests = []struct {
Frame
want string
}{{
Frame(initpc),
"github.com/pkg/errors/stack_test.go",
}}
for i, tt := range tests {
pc := tt.Frame.pc()
fn := runtime.FuncForPC(pc)
file, _ := fn.FileLine(pc)
got := trimGOPATH(fn.Name(), file)
testFormatRegexp(t, i, got, "%s", tt.want)
}
}
func TestStackTrace(t *testing.T) {
tests := []struct {
err error
@@ -120,24 +171,24 @@ func TestStackTrace(t *testing.T) {
}{{
New("ooh"), []string{
"github.com/pkg/errors.TestStackTrace\n" +
"\t.+/github.com/pkg/errors/stack_test.go:121",
"\t.+/github.com/pkg/errors/stack_test.go:172",
},
}, {
Wrap(New("ooh"), "ahh"), []string{
"github.com/pkg/errors.TestStackTrace\n" +
"\t.+/github.com/pkg/errors/stack_test.go:126", // this is the stack of Wrap, not New
"\t.+/github.com/pkg/errors/stack_test.go:177", // this is the stack of Wrap, not New
},
}, {
Cause(Wrap(New("ooh"), "ahh")), []string{
"github.com/pkg/errors.TestStackTrace\n" +
"\t.+/github.com/pkg/errors/stack_test.go:131", // this is the stack of New
"\t.+/github.com/pkg/errors/stack_test.go:182", // this is the stack of New
},
}, {
func() error { return New("ooh") }(), []string{
`github.com/pkg/errors.TestStackTrace.func1` +
"\n\t.+/github.com/pkg/errors/stack_test.go:136", // this is the stack of New
`github.com/pkg/errors.(func·009|TestStackTrace.func1)` +
"\n\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New
"github.com/pkg/errors.TestStackTrace\n" +
"\t.+/github.com/pkg/errors/stack_test.go:136", // this is the stack of New's caller
"\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New's caller
},
}, {
Cause(func() error {
@@ -145,12 +196,12 @@ func TestStackTrace(t *testing.T) {
return Errorf("hello %s", fmt.Sprintf("world"))
}()
}()), []string{
`github.com/pkg/errors.TestStackTrace.func2.1` +
"\n\t.+/github.com/pkg/errors/stack_test.go:145", // this is the stack of Errorf
`github.com/pkg/errors.TestStackTrace.func2` +
"\n\t.+/github.com/pkg/errors/stack_test.go:146", // this is the stack of Errorf's caller
`github.com/pkg/errors.(func·010|TestStackTrace.func2.1)` +
"\n\t.+/github.com/pkg/errors/stack_test.go:196", // this is the stack of Errorf
`github.com/pkg/errors.(func·011|TestStackTrace.func2)` +
"\n\t.+/github.com/pkg/errors/stack_test.go:197", // this is the stack of Errorf's caller
"github.com/pkg/errors.TestStackTrace\n" +
"\t.+/github.com/pkg/errors/stack_test.go:147", // this is the stack of Errorf's caller's caller
"\t.+/github.com/pkg/errors/stack_test.go:198", // this is the stack of Errorf's caller's caller
},
}}
for i, tt := range tests {
@@ -220,31 +271,22 @@ func TestStackTraceFormat(t *testing.T) {
}, {
stackTrace()[:2],
"%v",
`\[stack_test.go:174 stack_test.go:221\]`,
`\[stack_test.go:225 stack_test.go:272\]`,
}, {
stackTrace()[:2],
"%+v",
"\n" +
"github.com/pkg/errors.stackTrace\n" +
"\t.+/github.com/pkg/errors/stack_test.go:174\n" +
"\t.+/github.com/pkg/errors/stack_test.go:225\n" +
"github.com/pkg/errors.TestStackTraceFormat\n" +
"\t.+/github.com/pkg/errors/stack_test.go:225",
"\t.+/github.com/pkg/errors/stack_test.go:276",
}, {
stackTrace()[:2],
"%#v",
`\[\]errors.Frame{stack_test.go:174, stack_test.go:233}`,
`\[\]errors.Frame{stack_test.go:225, stack_test.go:284}`,
}}
for i, tt := range tests {
testFormatRegexp(t, i, tt.StackTrace, tt.format, tt.want)
}
}
// a version of runtime.Caller that returns a Frame, not a uintptr.
func caller() Frame {
var pcs [3]uintptr
n := runtime.Callers(2, pcs[:])
frames := runtime.CallersFrames(pcs[:n])
frame, _ := frames.Next()
return Frame(frame.PC)
}