Commit ef32eace authored by Russ Cox's avatar Russ Cox

go/build: change //build to // +build

New rules as discussed on CL 5011046.
Also apply to C and assembly files, not just Go files.

R=r, rogpeppe
CC=golang-dev
https://golang.org/cl/5015051
parent b955e265
...@@ -150,34 +150,39 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err os.Error) { ...@@ -150,34 +150,39 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err os.Error) {
continue continue
} }
isTest := false ext := path.Ext(d.Name)
switch path.Ext(d.Name) { switch ext {
case ".go": case ".go", ".c", ".s":
isTest = strings.HasSuffix(d.Name, "_test.go") // tentatively okay
case ".c":
di.CFiles = append(di.CFiles, d.Name)
continue
case ".s":
di.SFiles = append(di.SFiles, d.Name)
continue
default: default:
// skip
continue continue
} }
// Look for +build comments to accept or reject the file.
filename, data, err := ctxt.readFile(dir, d.Name) filename, data, err := ctxt.readFile(dir, d.Name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments) if !ctxt.shouldBuild(data) {
if err != nil { continue
return nil, err
} }
// Skip if the //build comments don't match. // Going to save the file. For non-Go files, can stop here.
if !ctxt.shouldBuild(pf) { switch ext {
case ".c":
di.CFiles = append(di.CFiles, d.Name)
continue
case ".s":
di.SFiles = append(di.SFiles, d.Name)
continue continue
} }
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
if err != nil {
return nil, err
}
pkg := string(pf.Name.Name) pkg := string(pf.Name.Name)
if pkg == "main" && di.Package != "" && di.Package != "main" { if pkg == "main" && di.Package != "" && di.Package != "main" {
continue continue
...@@ -185,6 +190,8 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err os.Error) { ...@@ -185,6 +190,8 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err os.Error) {
if pkg == "documentation" { if pkg == "documentation" {
continue continue
} }
isTest := strings.HasSuffix(d.Name, "_test.go")
if isTest && strings.HasSuffix(pkg, "_test") { if isTest && strings.HasSuffix(pkg, "_test") {
pkg = pkg[:len(pkg)-len("_test")] pkg = pkg[:len(pkg)-len("_test")]
} }
...@@ -279,24 +286,61 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err os.Error) { ...@@ -279,24 +286,61 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err os.Error) {
return &di, nil return &di, nil
} }
// okayBuild reports whether it is okay to build this Go file, var slashslash = []byte("//")
// based on the //build comments leading up to the package clause. var plusBuild = []byte("+build")
// shouldBuild reports whether it is okay to use this file,
// The rule is that in the file's leading run of // comments
// and blank lines, which must be followed by a blank line
// (to avoid including a Go package clause doc comment),
// lines beginning with '// +build' are taken as build directives.
// //
// The file is accepted only if each such line lists something // The file is accepted only if each such line lists something
// matching the file. For example: // matching the file. For example:
// //
// //build windows linux // // +build windows linux
// //
// marks the file as applicable only on Windows and Linux. // marks the file as applicable only on Windows and Linux.
func (ctxt *Context) shouldBuild(pf *ast.File) bool { //
for _, com := range pf.Comments { func (ctxt *Context) shouldBuild(content []byte) bool {
if com.Pos() >= pf.Package { // Pass 1. Identify leading run of // comments and blank lines,
// which must be followed by a blank line.
end := 0
p := content
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
}
line = bytes.TrimSpace(line)
if len(line) == 0 { // Blank line
end = cap(content) - cap(line) // &line[0] - &content[0]
continue
}
if !bytes.HasPrefix(line, slashslash) { // Not comment line
break break
} }
for _, c := range com.List { }
if strings.HasPrefix(c.Text, "//build") { content = content[:end]
f := strings.Fields(c.Text)
if f[0] == "//build" { // Pass 2. Process each line in the run.
p = content
for len(p) > 0 {
line := p
if i := bytes.IndexByte(line, '\n'); i >= 0 {
line, p = line[:i], p[i+1:]
} else {
p = p[len(p):]
}
line = bytes.TrimSpace(line)
if bytes.HasPrefix(line, slashslash) {
line = bytes.TrimSpace(line[len(slashslash):])
if len(line) > 0 && line[0] == '+' {
// Looks like a comment +line.
f := strings.Fields(string(line))
if f[0] == "+build" {
ok := false ok := false
for _, tok := range f[1:] { for _, tok := range f[1:] {
if ctxt.matchOSArch(tok) { if ctxt.matchOSArch(tok) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment