-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy patherror.go
84 lines (68 loc) · 2.05 KB
/
error.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package pcre
import (
"fmt"
"unsafe"
"go.elara.ws/pcre/lib"
"modernc.org/libc"
"modernc.org/libc/sys/types"
)
var pce pcreError
// pcreError is meant to be manually allocated
// for when pcre requires a pointer to store an error
// such as for Xpcre2_compile_8().
type pcreError struct {
errCode int32
errOffset lib.Tsize_t
}
// allocError manually allocates memory for the
// pcreError struct.
//
// libc.Xfree() should be called on the returned
// pointer once it is no longer needed.
func allocError(tls *libc.TLS) uintptr {
return libc.Xmalloc(tls, types.Size_t(unsafe.Sizeof(pce)))
}
// addErrCodeOffset adds the offset of the error code
// within the pcreError struct to a given pointer
func addErrCodeOffset(p uintptr) uintptr {
ptrOffset := unsafe.Offsetof(pce.errCode)
return p + ptrOffset
}
// addErrOffsetOffset adds the offset of the error
// offset within the pcreError struct to a given pointer
func addErrOffsetOffset(p uintptr) uintptr {
offsetOffset := unsafe.Offsetof(pce.errOffset)
return p + offsetOffset
}
// ptrToError converts the given pointer to a Go error
func ptrToError(tls *libc.TLS, pe uintptr) *PcreError {
eo := *(*pcreError)(unsafe.Pointer(pe))
err := codeToError(tls, eo.errCode)
err.offset = eo.errOffset
err.hasOffset = true
return err
}
// codeToError converts the given error code into a Go error
func codeToError(tls *libc.TLS, code int32) *PcreError {
errBuf := make([]byte, 256)
cErrBuf := uintptr(unsafe.Pointer(&errBuf[0]))
// Get the textual error message associated with the code,
// and store it in errBuf.
msgLen := lib.Xpcre2_get_error_message_8(tls, code, cErrBuf, 256)
return &PcreError{false, 0, string(errBuf[:msgLen])}
}
// PcreError represents errors returned
// by underlying pcre2 functions.
type PcreError struct {
hasOffset bool
offset lib.Tsize_t
errStr string
}
// Error returns the string within the error,
// prepending the offset if it exists.
func (pe *PcreError) Error() string {
if !pe.hasOffset {
return pe.errStr
}
return fmt.Sprintf("offset %d: %s", pe.offset, pe.errStr)
}