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) {
continue
}
isTest := false
switch path.Ext(d.Name) {
case ".go":
isTest = strings.HasSuffix(d.Name, "_test.go")
case ".c":
di.CFiles = append(di.CFiles, d.Name)
continue
case ".s":
di.SFiles = append(di.SFiles, d.Name)
continue
ext := path.Ext(d.Name)
switch ext {
case ".go", ".c", ".s":
// tentatively okay
default:
// skip
continue
}
// Look for +build comments to accept or reject the file.
filename, data, err := ctxt.readFile(dir, d.Name)
if err != nil {
return nil, err
}
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
if err != nil {
return nil, err
if !ctxt.shouldBuild(data) {
continue
}
// Skip if the //build comments don't match.
if !ctxt.shouldBuild(pf) {
// Going to save the file. For non-Go files, can stop here.
switch ext {
case ".c":
di.CFiles = append(di.CFiles, d.Name)
continue
case ".s":
di.SFiles = append(di.SFiles, d.Name)
continue
}
pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly|parser.ParseComments)
if err != nil {
return nil, err
}
pkg := string(pf.Name.Name)
if pkg == "main" && di.Package != "" && di.Package != "main" {
continue
......@@ -185,6 +190,8 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err os.Error) {
if pkg == "documentation" {
continue
}
isTest := strings.HasSuffix(d.Name, "_test.go")
if isTest && strings.HasSuffix(pkg, "_test") {
pkg = pkg[:len(pkg)-len("_test")]
}
......@@ -279,24 +286,61 @@ func (ctxt *Context) ScanDir(dir string) (info *DirInfo, err os.Error) {
return &di, nil
}
// okayBuild reports whether it is okay to build this Go file,
// based on the //build comments leading up to the package clause.
var slashslash = []byte("//")
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
// matching the file. For example:
//
// //build windows linux
// // +build windows linux
//
// marks the file as applicable only on Windows and Linux.
func (ctxt *Context) shouldBuild(pf *ast.File) bool {
for _, com := range pf.Comments {
if com.Pos() >= pf.Package {
//
func (ctxt *Context) shouldBuild(content []byte) bool {
// 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
}
for _, c := range com.List {
if strings.HasPrefix(c.Text, "//build") {
f := strings.Fields(c.Text)
if f[0] == "//build" {
}
content = content[:end]
// 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
for _, tok := range f[1:] {
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