-
Notifications
You must be signed in to change notification settings - Fork 2
/
line.go
104 lines (89 loc) · 2.98 KB
/
line.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
package specfile
import (
"strings"
"unicode"
"unicode/utf8"
)
var (
dependencyMap = map[string]struct{}{"BuildRequires": {}, "Requires": {}, "Obsoletes": {}, "Provides": {}, "Conflicts": {}, "Recommends": {}, "Supplements": {}, "Suggests": {}, "Enhances": {}}
sectionMap = map[string]struct{}{"%package": {}, "%prep": {}, "generate_buildrequires": {}, "%build": {}, "%install": {}, "%check": {}, "%clean": {}, "%preun": {}, "%postun": {}, "%pretrans": {}, "%posttrans": {}, "%pre": {}, "%post": {}, "%files": {}, "%changelog": {}, "%description": {}, "%triggerpostun": {}, "%triggerprein": {}, "%triggerun": {}, "%triggerin": {}, "%trigger": {}, "%verifyscript": {}, "%sepolicy": {}, "%filetriggerin": {}, "%filetrigger": {}, "%filetriggerun": {}, "%filetriggerpostun": {}, "%transfiletriggerin": {}, "%transfiletrigger": {}, "%transfiletriggerun": {}, "%transfiletriggerpostun": {}, "%patchlist": {}, "%sourcelist": {}}
conditionalIndicators = []string{"%if", "%else", "%elif", "%end"}
)
// Line information for a syntactically valid line
type Line struct {
Lines []string
Last string
Len int
Offset int64
}
// NewLine initialize a new Line
func NewLine(offset int64, lines ...string) Line {
last := ""
if len(lines) > 0 {
last = lines[len(lines)-1]
}
return Line{lines, last, len(lines), offset}
}
// isConditional if a Line is a conditional line
func (line Line) isConditional() bool {
for _, c := range conditionalIndicators {
if strings.HasPrefix(line.Last, c) {
return true
}
}
return false
}
// isSection if the line is a specfile section like %build, %install
func (line Line) isSection() bool {
for section := range sectionMap {
// section indicator must be itself like "%files" or with whitespaces like "%files -n"
// or "%install" will match "%install_info"
if strings.HasPrefix(line.Last, section+"\n") || strings.HasPrefix(line.Last, section+" ") {
return true
}
}
return false
}
// isMacro if the line is a rpm macro like "%define fcitx5_version 5.0.1"
func (line Line) isMacro() bool {
if strings.HasPrefix(line.Last, "%define") || strings.HasPrefix(line.Last, "%global") {
return true
}
return false
}
// isDependency if the line is a dependency tag
func (line Line) isDependency() bool {
for k := range dependencyMap {
if strings.HasPrefix(line.Last, k) {
return true
}
}
return false
}
// isTag if the line is a rpm tag like "Name: xz"
func (line Line) isTag() bool {
if len(strings.TrimSpace(line.Last)) == 0 {
return false
}
r, _ := utf8.DecodeRuneInString(line.Last)
return unicode.IsUpper(r)
}
// Concat prepend or append lines of string to Line struct
func (line *Line) Concat(prepend bool, lines ...string) {
// don't append empty bytes
if len(lines) == 1 && len(lines[0]) == 0 {
return
}
old := line.Lines
new := lines
if prepend {
old = lines
new = line.Lines
}
line.Len = line.Len + len(lines)
for _, v := range new {
old = append(old, v)
}
line.Lines = old
line.Last = line.Lines[len(line.Lines)-1]
}