-
Notifications
You must be signed in to change notification settings - Fork 0
/
source.go
77 lines (67 loc) · 1.61 KB
/
source.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
package source // import "sevki.org/x/source"
import (
"regexp"
"sort"
"strconv"
)
// Error represents an errror in the srouce code
type Error struct {
File string
Line, Column int
Message string
}
/*
Parse a message that is almost the standard in error messages that are outputed by
most modern compilers and tools that work with source code
format is either
xxx.yyy:01:01: some message
{filename}.{fileext}:{line}:{column}: {message}
or
xxx.yyy:01: some message
{filename}.{fileext}:{line}: {message}
*/
var validMessage = regexp.MustCompile(`([[:alnum:]]+.[[:alnum:]]+):([0-9]+):([0-9]+)?:? (.*)`)
// ParseSourceErrors takes the log of a process and
// returns it's sourcecode errors
func ParseSourceErrors(message string) []Error {
var errors []Error
messages := validMessage.FindAllStringSubmatch(message, -1)
for _, message := range messages {
e := Error{
File: message[1],
}
if line, err := strconv.Atoi(message[2]); err == nil {
e.Line = line
}
if column, err := strconv.Atoi(message[3]); err == nil {
e.Column = column
} else {
e.Column = -1
e.Message = message[3]
}
if len(message) > 3 {
e.Message = message[4]
}
errors = append(errors, e)
}
return errors
}
func GetRangesFromErrors(errors []Error, tolerance int) []int {
nums := make(map[int]bool)
for _, err := range errors {
start := 1
if err.Line-tolerance > start {
start = err.Line - tolerance
}
end := err.Line + tolerance + 1
for i := start; i < end; i++ {
nums[i] = true
}
}
var lines []int
for line := range nums {
lines = append(lines, line)
}
sort.Ints(lines)
return lines
}