This repository has been archived by the owner on Feb 17, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
component.go
158 lines (141 loc) · 3.71 KB
/
component.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
package buildbuild
import (
"errors"
"path"
)
var (
UnhandledBuildDirective = errors.New("Unhandled build directive")
MissingOpenParen = errors.New("Missing open parenthesis")
MissingCloseParen = errors.New("Missing close parenthesis")
DuplicateConfig = errors.New("Duplicate CONFIG or CONFIG wasn't first")
UnexpectedEOF = errors.New("Unexpected end of file")
)
type ParseError struct {
Err error
Token string
Builddesc string
}
func (e *ParseError) Error() string {
return e.Builddesc + ": " + e.Err.Error() + " near " + e.Token
}
func panicOrEOF(s *Scanner) {
err := s.Err()
if err == nil {
err = &ParseError{UnexpectedEOF, "", s.Filename}
}
panic(err)
}
func panicIfErr(s *Scanner) {
if err := s.Err(); err != nil {
panic(err)
}
}
type ParseFunc func(string, *Scanner, []string) ParseFunc
func (ops *GlobalOps) ParseDirective(srcdir string, s *Scanner, flavors []string) ParseFunc {
if !s.Scan() {
panicIfErr(s)
return nil
}
dname := s.Text()
if !s.Scan() {
panicOrEOF(s)
}
if s.Text() != "(" {
panic(&ParseError{MissingOpenParen, s.Text(), s.Filename})
}
confseen := ops.Config.Seen
ops.Config.Seen = true
if dname == "CONFIG" {
if confseen {
panic(&ParseError{DuplicateConfig, dname, s.Filename})
}
return ops.ParseConfig
}
if !confseen && ops.PostConfigFunc != nil {
if err := ops.PostConfigFunc(ops); err != nil {
panic(err)
}
}
if dname == "COMPONENT" {
return ops.ParseComponent
}
if defdesc := PluginDescriptors[dname]; defdesc != nil {
dp := &DescParser{ops, defdesc}
return dp.Parse
}
if defdesc := DefaultDescriptors[dname]; defdesc != nil {
dp := &DescParser{ops, defdesc}
return dp.Parse
}
panic(&ParseError{UnhandledBuildDirective, dname, s.Filename})
}
type DescParser struct {
Ops *GlobalOps
DefDesc Descriptor
}
func (dp *DescParser) Parse(srcdir string, s *Scanner, flavors []string) ParseFunc {
if !s.Scan() {
panicOrEOF(s)
}
tname := s.Text()
var args Args
haveEnabled := args.Parse(s, dp.Ops.CheckConditions)
if flavors == nil {
flavors = dp.Ops.Config.ActiveFlavors
}
descFlavors := args.Unflavored["flavors"]
if len(descFlavors) == 0 {
if len(args.Flavors) > 0 {
// If we have flavored arguments, we need to split the descriptors.
descFlavors = flavors
} else {
descFlavors = []string{""}
}
}
delete(args.Unflavored, "flavors")
for _, fl := range descFlavors {
flargs := make(map[string][]string)
for k, v := range args.Unflavored {
flargs[k] = v
}
for k, v := range args.Flavors[fl] {
flargs[k] = append(flargs[k], v...)
}
// If an enabled argument exists then skip this descriptor if
// it's not currently set.
if _, ok := flargs["enabled"]; haveEnabled && !ok {
continue
}
delete(flargs, "enabled")
onlyForFlavors := flavors
if fl != "" {
onlyForFlavors = []string{fl}
}
desc := dp.DefDesc.NewFromTemplate(s.Filename, tname, onlyForFlavors)
desc = desc.Parse(dp.Ops, srcdir, flargs)
dp.Ops.Descriptors = append(dp.Ops.Descriptors, desc)
}
return dp.Ops.ParseDescriptorEnd
}
func (ops *GlobalOps) ParseDescriptorEnd(srcdir string, s *Scanner, flavors []string) ParseFunc {
if s.Text() != ")" {
panic(&ParseError{MissingCloseParen, s.Text(), s.Filename})
}
return ops.ParseDirective
}
func (ops *GlobalOps) ParseComponent(srcdir string, s *Scanner, flavors []string) ParseFunc {
var args Args
args.Parse(s, ops.CheckConditions)
if args.Unflavored["flavors"] != nil {
flavors = args.Unflavored["flavors"]
}
for _, comp := range args.Unflavored[""] {
// XXX comp = normalizePath(srcdir, comp)
comp = path.Join(srcdir, comp)
err := ops.ReadComponent(comp, flavors)
if err != nil {
panic(err)
}
}
return ops.ParseDescriptorEnd
}