diff options
author | Tobias Bosch <tbosch@google.com> | 2019-06-24 09:31:39 -0700 |
---|---|---|
committer | Tobias Bosch <tbosch@google.com> | 2019-06-28 19:00:23 +0000 |
commit | 900dbc92800d8fc927905db29cb302461054cf97 (patch) | |
tree | c74ecbfb01ee4ee679090139596aef3546f19d9b /compiler_wrapper/errors.go | |
parent | 739e6abb2cd03b60e579df31ad55870a4a00260a (diff) | |
download | toolchain-utils-900dbc92800d8fc927905db29cb302461054cf97.tar.gz |
Introduce infrastructure for calling and testing nested
commands, error messages and exit codes.
Also:
- implements the -Xclang-path= flag as use case of calling
a nested command.
- adds tests for forwarding errors, comparing against the
old wrapper, and exit codes.
- captures the source locations of errors in error messages.
- compares exit codes of new wrapper and old wrapper.
BUG=chromium:773875
TEST=unit test
Change-Id: I919e58091d093d68939809f676f799a68ec7a34e
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/1676833
Reviewed-by: George Burgess <gbiv@chromium.org>
Tested-by: Tobias Bosch <tbosch@google.com>
Diffstat (limited to 'compiler_wrapper/errors.go')
-rw-r--r-- | compiler_wrapper/errors.go | 57 |
1 files changed, 57 insertions, 0 deletions
diff --git a/compiler_wrapper/errors.go b/compiler_wrapper/errors.go new file mode 100644 index 00000000..525b986e --- /dev/null +++ b/compiler_wrapper/errors.go @@ -0,0 +1,57 @@ +package main + +import ( + "fmt" + "os/exec" + "runtime" + "strings" + "syscall" +) + +type userError struct { + err string +} + +var _ error = userError{} + +func (err userError) Error() string { + return err.err +} + +func newUserErrorf(format string, v ...interface{}) userError { + return userError{err: fmt.Sprintf(format, v...)} +} + +func newErrorwithSourceLocf(format string, v ...interface{}) error { + return newErrorwithSourceLocfInternal(2, format, v...) +} + +func wrapErrorwithSourceLocf(err error, format string, v ...interface{}) error { + return newErrorwithSourceLocfInternal(2, "%s: %s", fmt.Sprintf(format, v...), err.Error()) +} + +// Based on the implementation of log.Output +func newErrorwithSourceLocfInternal(skip int, format string, v ...interface{}) error { + _, file, line, ok := runtime.Caller(skip) + if !ok { + file = "???" + line = 0 + } + if lastSlash := strings.LastIndex(file, "/"); lastSlash >= 0 { + file = file[lastSlash+1:] + } + + return fmt.Errorf("%s:%d: %s", file, line, fmt.Sprintf(format, v...)) +} + +func getExitCode(err error) (exitCode int, ok bool) { + if err == nil { + return 0, true + } + if exiterr, ok := err.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + return status.ExitStatus(), true + } + } + return 0, false +} |