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
|
package main
import (
"fmt"
"io"
"path"
"strings"
)
type LogLevel struct {
TraditionalName string
GccName string
}
var (
llFatal = &LogLevel{"FATAL", "fatal"}
llError = &LogLevel{"ERROR", "error"}
llWarn = &LogLevel{"WARN", "warning"}
llNote = &LogLevel{"NOTE", "note"}
llAutofix = &LogLevel{"AUTOFIX", "autofix"}
)
var dummyLine = NewLine("", 0, "", nil)
func shallBeLogged(fname, lineno, msg string) bool {
uniq := path.Clean(fname) + ":" + lineno + ":" + msg
if G.logged[uniq] {
return false
}
if G.logged == nil {
G.logged = make(map[string]bool)
}
G.logged[uniq] = true
return true
}
func logs(level *LogLevel, fname, lineno, format, msg string) bool {
if fname != "" {
fname = cleanpath(fname)
}
if !G.opts.LogVerbose && !shallBeLogged(fname, lineno, msg) {
return false
}
var text, sep string
if !G.opts.GccOutput {
text += sep + level.TraditionalName + ":"
sep = " "
}
if fname != "" {
text += sep + fname
sep = ": "
if lineno != "" {
text += ":" + lineno
}
}
if G.opts.GccOutput {
text += sep + level.GccName + ":"
sep = " "
}
if G.opts.Profiling {
G.loghisto.Add(format, 1)
}
text += sep + msg + "\n"
out := G.logOut
if level == llFatal {
out = G.logErr
}
io.WriteString(out, text)
switch level {
case llFatal:
panic(pkglintFatal{})
case llError:
G.errors++
case llWarn:
G.warnings++
}
return true
}
func Explain(explanation ...string) {
if G.opts.Explain {
complete := strings.Join(explanation, "\n")
if G.explanationsGiven[complete] {
return
}
if G.explanationsGiven == nil {
G.explanationsGiven = make(map[string]bool)
}
G.explanationsGiven[complete] = true
io.WriteString(G.logOut, "\n")
for _, explanationLine := range explanation {
io.WriteString(G.logOut, "\t"+explanationLine+"\n")
}
io.WriteString(G.logOut, "\n")
} else if G.Testing {
for _, s := range explanation {
if l := tabLength(s); l > 68 && contains(s, " ") {
print(fmt.Sprintf("Long explanation line (%d): %s\n", l, s))
}
if m, before := match1(s, `(.+)\. [^ ]`); m {
if !matches(before, `\d$|e\.g`) {
print(fmt.Sprintf("Short space after period: %s\n", s))
}
}
}
}
G.explanationsAvailable = true
}
type pkglintFatal struct{}
|