-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdebug.go
143 lines (124 loc) · 3.15 KB
/
debug.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package debug
import (
"bufio"
"bytes"
"fmt"
"go/token"
"os"
"runtime"
"strings"
"time"
)
const (
delimiterBeg string = `[ %02d.%02d.%04d %02d:%02d:%02d:%010d ] ------------------------------------------------------------`
delimiterEnd string = `-----------------------------------------------------------------------------------------------`
lineEnd string = "\n"
lineEndCRLF string = "\r\n"
)
var (
defaultCRLF bool // For operating systems with the end of line CRLF or set environment value DEBUG_CRLF=true or DEBUG_CRLF=false
seeCalls bool // Search on a large project forgotten debug calls. Set to true by environment value DEBUG_CALLS=true
seeTrace bool // Printing with the bump data call stack. Set to true by set environment value DEBUG_TRACESTACK=true
)
type debug struct {
Result *bytes.Buffer
Buffer *bytes.Buffer
ReadWriter *bufio.ReadWriter
UseCRLF bool
Now time.Time
Trace *trace
}
func init() {
const (
false = `false`
windows = `windows`
calls = `DEBUG_CALLS`
crlf = `DEBUG_CRLF`
tracestack = `DEBUG_TRACESTACK`
)
switch runtime.GOOS {
case windows:
defaultCRLF = true
}
if os.Getenv(calls) != "" {
if strings.EqualFold(os.Getenv(calls), false) != true {
seeCalls = true
}
}
if os.Getenv(crlf) != "" {
if strings.EqualFold(os.Getenv(crlf), false) != true {
defaultCRLF = true
}
}
if os.Getenv(tracestack) != "" {
if strings.EqualFold(os.Getenv(tracestack), false) != true {
seeTrace = true
}
}
}
func newDebug() (obj *debug) {
var buf = &bytes.Buffer{}
obj = &debug{
Result: &bytes.Buffer{},
Buffer: buf,
ReadWriter: bufio.NewReadWriter(bufio.NewReader(buf), bufio.NewWriter(buf)),
UseCRLF: defaultCRLF,
Now: time.Now().In(time.Local),
Trace: newTrace().Trace(traceStepBack + 1),
}
return
}
// Dump all variables
func (d *debug) Dump(idl ...interface{}) *debug {
var (
i int
fset *token.FileSet
)
for i = range idl {
fset = token.NewFileSet()
_ = printerPrint(d.ReadWriter, fset, idl[i], notNilFilter)
}
// call stack
if seeTrace {
_, _ = d.ReadWriter.WriteString(d.Trace.Stack + lineEnd)
}
return d
}
// Add information before dump
func (d *debug) Prefix(fn string) *debug {
_, _ = d.ReadWriter.WriteString(fmt.Sprintf(delimiterBeg+lineEnd, d.Now.Day(), d.Now.Month(), d.Now.Year(), d.Now.Hour(), d.Now.Minute(), d.Now.Second(), d.Now.Nanosecond()))
_, _ = d.ReadWriter.WriteString(fmt.Sprintf("[ %30s ] %s:%d [%s] [%s()]"+lineEnd, fn, d.Trace.File, d.Trace.Line, d.Trace.Package, d.Trace.Function))
return d
}
// Add information after dump
func (d *debug) Suffix() *debug {
_, _ = d.ReadWriter.WriteString(delimiterEnd + lineEnd)
return d
}
// Finalisation dump
func (d *debug) Final() *bytes.Buffer {
var (
line []byte
isPrefix bool
err error
)
_ = d.ReadWriter.Flush()
for {
line, isPrefix, err = d.ReadWriter.ReadLine()
_, _ = d.Result.Write(line)
if isPrefix {
continue
}
if len(line) > 0 {
if d.UseCRLF {
_, _ = d.Result.WriteString(lineEndCRLF)
} else {
_, _ = d.Result.WriteString(lineEnd)
}
}
if err != nil {
break
}
}
return d.Result
}