Source file src/pkg/cmd/go/internal/imports/build.go
1
2
3
4
5
6
7 package imports
8
9 import (
10 "bytes"
11 "strings"
12 "unicode"
13 )
14
15 var slashslash = []byte("//")
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 func ShouldBuild(content []byte, tags map[string]bool) bool {
37
38
39 end := 0
40 p := content
41 for len(p) > 0 {
42 line := p
43 if i := bytes.IndexByte(line, '\n'); i >= 0 {
44 line, p = line[:i], p[i+1:]
45 } else {
46 p = p[len(p):]
47 }
48 line = bytes.TrimSpace(line)
49 if len(line) == 0 {
50 end = len(content) - len(p)
51 continue
52 }
53 if !bytes.HasPrefix(line, slashslash) {
54 break
55 }
56 }
57 content = content[:end]
58
59
60 p = content
61 allok := true
62 for len(p) > 0 {
63 line := p
64 if i := bytes.IndexByte(line, '\n'); i >= 0 {
65 line, p = line[:i], p[i+1:]
66 } else {
67 p = p[len(p):]
68 }
69 line = bytes.TrimSpace(line)
70 if !bytes.HasPrefix(line, slashslash) {
71 continue
72 }
73 line = bytes.TrimSpace(line[len(slashslash):])
74 if len(line) > 0 && line[0] == '+' {
75
76 f := strings.Fields(string(line))
77 if f[0] == "+build" {
78 ok := false
79 for _, tok := range f[1:] {
80 if matchTags(tok, tags) {
81 ok = true
82 }
83 }
84 if !ok {
85 allok = false
86 }
87 }
88 }
89 }
90
91 return allok
92 }
93
94
95
96
97
98
99
100 func matchTags(name string, tags map[string]bool) bool {
101 if name == "" {
102 return false
103 }
104 if i := strings.Index(name, ","); i >= 0 {
105
106 ok1 := matchTags(name[:i], tags)
107 ok2 := matchTags(name[i+1:], tags)
108 return ok1 && ok2
109 }
110 if strings.HasPrefix(name, "!!") {
111 return false
112 }
113 if strings.HasPrefix(name, "!") {
114 return len(name) > 1 && matchTag(name[1:], tags, false)
115 }
116 return matchTag(name, tags, true)
117 }
118
119
120 func matchTag(name string, tags map[string]bool, want bool) bool {
121
122
123 for _, c := range name {
124 if !unicode.IsLetter(c) && !unicode.IsDigit(c) && c != '_' && c != '.' {
125 return false
126 }
127 }
128
129 if tags["*"] && name != "" && name != "ignore" {
130
131
132
133
134 return true
135 }
136
137 have := tags[name]
138 if name == "linux" {
139 have = have || tags["android"]
140 }
141 if name == "solaris" {
142 have = have || tags["illumos"]
143 }
144 return have == want
145 }
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165 func MatchFile(name string, tags map[string]bool) bool {
166 if tags["*"] {
167 return true
168 }
169 if dot := strings.Index(name, "."); dot != -1 {
170 name = name[:dot]
171 }
172
173
174
175
176
177
178
179
180 i := strings.Index(name, "_")
181 if i < 0 {
182 return true
183 }
184 name = name[i:]
185
186 l := strings.Split(name, "_")
187 if n := len(l); n > 0 && l[n-1] == "test" {
188 l = l[:n-1]
189 }
190 n := len(l)
191 if n >= 2 && KnownOS[l[n-2]] && KnownArch[l[n-1]] {
192 return matchTag(l[n-2], tags, true) && matchTag(l[n-1], tags, true)
193 }
194 if n >= 1 && KnownOS[l[n-1]] {
195 return matchTag(l[n-1], tags, true)
196 }
197 if n >= 1 && KnownArch[l[n-1]] {
198 return matchTag(l[n-1], tags, true)
199 }
200 return true
201 }
202
203 var KnownOS = map[string]bool{
204 "aix": true,
205 "android": true,
206 "darwin": true,
207 "dragonfly": true,
208 "freebsd": true,
209 "hurd": true,
210 "illumos": true,
211 "js": true,
212 "linux": true,
213 "nacl": true,
214 "netbsd": true,
215 "openbsd": true,
216 "plan9": true,
217 "solaris": true,
218 "windows": true,
219 "zos": true,
220 }
221
222 var KnownArch = map[string]bool{
223 "386": true,
224 "amd64": true,
225 "amd64p32": true,
226 "arm": true,
227 "armbe": true,
228 "arm64": true,
229 "arm64be": true,
230 "ppc64": true,
231 "ppc64le": true,
232 "mips": true,
233 "mipsle": true,
234 "mips64": true,
235 "mips64le": true,
236 "mips64p32": true,
237 "mips64p32le": true,
238 "ppc": true,
239 "riscv": true,
240 "riscv64": true,
241 "s390": true,
242 "s390x": true,
243 "sparc": true,
244 "sparc64": true,
245 "wasm": true,
246 }
247
View as plain text