"go/scanner"
"go/token"
"os"
- "path/filepath"
"strings"
)
// attached to the import "C" comment, a list of references to C.xxx,
// a list of exported functions, and the actual AST, to be rewritten and
// printed.
-func (f *File) ParseGo(name string, src []byte) {
- // Create absolute path for file, so that it will be used in error
- // messages and recorded in debug line number information.
- // This matches the rest of the toolchain. See golang.org/issue/5122.
- if aname, err := filepath.Abs(name); err == nil {
- name = aname
- }
-
+func (f *File) ParseGo(abspath string, src []byte) {
// Two different parses: once with comments, once without.
// The printer is not good enough at printing comments in the
// right place when we start editing the AST behind its back,
// and reprinting.
// In cgo mode, we ignore ast2 and just apply edits directly
// the text behind ast1. In godefs mode we modify and print ast2.
- ast1 := parse(name, src, parser.ParseComments)
- ast2 := parse(name, src, 0)
+ ast1 := parse(abspath, src, parser.ParseComments)
+ ast2 := parse(abspath, src, 0)
f.Package = ast1.Name.Name
f.Name = make(map[string]*Name)
cg = d.Doc
}
if cg != nil {
- f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), name)
+ f.Preamble += fmt.Sprintf("#line %d %q\n", sourceLine(cg), abspath)
f.Preamble += commentText(cg) + "\n"
f.Preamble += "#line 1 \"cgo-generated-wrapper\"\n"
}
)
// godefs returns the output for -godefs mode.
-func (p *Package) godefs(f *File, srcfile string) string {
+func (p *Package) godefs(f *File) string {
var buf bytes.Buffer
fmt.Fprintf(&buf, "// Code generated by cmd/cgo -godefs; DO NOT EDIT.\n")
var gccgoMangler func(string) string
var importRuntimeCgo = flag.Bool("import_runtime_cgo", true, "import runtime/cgo in generated code")
var importSyscall = flag.Bool("import_syscall", true, "import syscall in generated code")
+var trimpath = flag.String("trimpath", "", "applies supplied rewrites or trims prefixes to recorded source file paths")
+
var goarch, goos string
func main() {
input = filepath.Join(*srcDir, input)
}
+ // Create absolute path for file, so that it will be used in error
+ // messages and recorded in debug line number information.
+ // This matches the rest of the toolchain. See golang.org/issue/5122.
+ if aname, err := filepath.Abs(input); err == nil {
+ input = aname
+ }
+
b, err := ioutil.ReadFile(input)
if err != nil {
fatalf("%s", err)
fatalf("%s", err)
}
+ // Apply trimpath to the file path. The path won't be read from after this point.
+ input, _ = objabi.ApplyRewrites(input, *trimpath)
+ goFiles[i] = input
+
f := new(File)
f.Edit = edit.NewBuffer(b)
f.ParseGo(input, b)
p.PackagePath = f.Package
p.Record(f)
if *godefs {
- os.Stdout.WriteString(p.godefs(f, input))
+ os.Stdout.WriteString(p.godefs(f))
} else {
p.writeOutput(f, input)
}
abs = filepath.Join(dir, file)
}
+ abs, rewritten := ApplyRewrites(abs, rewrites)
+ if !rewritten && hasPathPrefix(abs, GOROOT) {
+ abs = "$GOROOT" + abs[len(GOROOT):]
+ }
+
+ if abs == "" {
+ abs = "??"
+ }
+ return abs
+}
+
+// ApplyRewrites returns the filename for file in the given directory,
+// as rewritten by the rewrites argument.
+//
+// The rewrites argument is a ;-separated list of rewrites.
+// Each rewrite is of the form "prefix" or "prefix=>replace",
+// where prefix must match a leading sequence of path elements
+// and is either removed entirely or replaced by the replacement.
+func ApplyRewrites(file, rewrites string) (string, bool) {
start := 0
for i := 0; i <= len(rewrites); i++ {
if i == len(rewrites) || rewrites[i] == ';' {
- if new, ok := applyRewrite(abs, rewrites[start:i]); ok {
- abs = new
- goto Rewritten
+ if new, ok := applyRewrite(file, rewrites[start:i]); ok {
+ return new, true
}
start = i + 1
}
}
- if hasPathPrefix(abs, GOROOT) {
- abs = "$GOROOT" + abs[len(GOROOT):]
- }
-Rewritten:
- if abs == "" {
- abs = "??"
- }
- return abs
+ return file, false
}
// applyRewrite applies the rewrite to the path,