summaryrefslogtreecommitdiff
path: root/src/cmd/cgo/main.go
diff options
context:
space:
mode:
authorOndřej Surý <ondrej@sury.org>2011-09-13 13:11:55 +0200
committerOndřej Surý <ondrej@sury.org>2011-09-13 13:11:55 +0200
commit80f18fc933cf3f3e829c5455a1023d69f7b86e52 (patch)
tree4b825dc642cb6eb9a060e54bf8d69288fbee4904 /src/cmd/cgo/main.go
parent28592ee1ea1f5cdffcf85472f9de0285d928cf12 (diff)
downloadgolang-80f18fc933cf3f3e829c5455a1023d69f7b86e52.tar.gz
Imported Upstream version 60
Diffstat (limited to 'src/cmd/cgo/main.go')
-rw-r--r--src/cmd/cgo/main.go268
1 files changed, 0 insertions, 268 deletions
diff --git a/src/cmd/cgo/main.go b/src/cmd/cgo/main.go
deleted file mode 100644
index be9c2bc4f..000000000
--- a/src/cmd/cgo/main.go
+++ /dev/null
@@ -1,268 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Cgo; see gmp.go for an overview.
-
-// TODO(rsc):
-// Emit correct line number annotations.
-// Make 6g understand the annotations.
-
-package main
-
-import (
- "crypto/md5"
- "flag"
- "fmt"
- "go/ast"
- "go/token"
- "io"
- "os"
- "path/filepath"
- "reflect"
- "strings"
-)
-
-// A Package collects information about the package we're going to write.
-type Package struct {
- PackageName string // name of package
- PackagePath string
- PtrSize int64
- GccOptions []string
- CgoFlags map[string]string // #cgo flags (CFLAGS, LDFLAGS)
- Written map[string]bool
- Name map[string]*Name // accumulated Name from Files
- Typedef map[string]ast.Expr // accumulated Typedef from Files
- ExpFunc []*ExpFunc // accumulated ExpFunc from Files
- Decl []ast.Decl
- GoFiles []string // list of Go files
- GccFiles []string // list of gcc output files
-}
-
-// A File collects information about a single Go input file.
-type File struct {
- AST *ast.File // parsed AST
- Package string // Package name
- Preamble string // C preamble (doc comment on import "C")
- Ref []*Ref // all references to C.xxx in AST
- ExpFunc []*ExpFunc // exported functions for this file
- Name map[string]*Name // map from Go name to Name
- Typedef map[string]ast.Expr // translations of all necessary types from C
-}
-
-// A Ref refers to an expression of the form C.xxx in the AST.
-type Ref struct {
- Name *Name
- Expr *ast.Expr
- Context string // "type", "expr", "call", or "call2"
-}
-
-func (r *Ref) Pos() token.Pos {
- return (*r.Expr).Pos()
-}
-
-// A Name collects information about C.xxx.
-type Name struct {
- Go string // name used in Go referring to package C
- Mangle string // name used in generated Go
- C string // name used in C
- Define string // #define expansion
- Kind string // "const", "type", "var", "func", "not-type"
- Type *Type // the type of xxx
- FuncType *FuncType
- AddError bool
- Const string // constant definition
-}
-
-// A ExpFunc is an exported function, callable from C.
-// Such functions are identified in the Go input file
-// by doc comments containing the line //export ExpName
-type ExpFunc struct {
- Func *ast.FuncDecl
- ExpName string // name to use from C
-}
-
-// A TypeRepr contains the string representation of a type.
-type TypeRepr struct {
- Repr string
- FormatArgs []interface{}
-}
-
-// A Type collects information about a type in both the C and Go worlds.
-type Type struct {
- Size int64
- Align int64
- C *TypeRepr
- Go ast.Expr
- EnumValues map[string]int64
-}
-
-// A FuncType collects information about a function type in both the C and Go worlds.
-type FuncType struct {
- Params []*Type
- Result *Type
- Go *ast.FuncType
-}
-
-func usage() {
- fmt.Fprint(os.Stderr, "usage: cgo -- [compiler options] file.go ...\n")
- flag.PrintDefaults()
- os.Exit(2)
-}
-
-var ptrSizeMap = map[string]int64{
- "386": 4,
- "amd64": 8,
- "arm": 4,
-}
-
-var cPrefix string
-
-var fset = token.NewFileSet()
-
-var dynobj = flag.String("dynimport", "", "if non-empty, print dynamic import data for that file")
-
-func main() {
- flag.Usage = usage
- flag.Parse()
-
- if *dynobj != "" {
- // cgo -dynimport is essentially a separate helper command
- // built into the cgo binary. It scans a gcc-produced executable
- // and dumps information about the imported symbols and the
- // imported libraries. The Make.pkg rules for cgo prepare an
- // appropriate executable and then use its import information
- // instead of needing to make the linkers duplicate all the
- // specialized knowledge gcc has about where to look for imported
- // symbols and which ones to use.
- dynimport(*dynobj)
- return
- }
-
- args := flag.Args()
- if len(args) < 1 {
- usage()
- }
-
- // Find first arg that looks like a go file and assume everything before
- // that are options to pass to gcc.
- var i int
- for i = len(args); i > 0; i-- {
- if !strings.HasSuffix(args[i-1], ".go") {
- break
- }
- }
- if i == len(args) {
- usage()
- }
-
- // Copy it to a new slice so it can grow.
- gccOptions := make([]string, i)
- copy(gccOptions, args[0:i])
-
- goFiles := args[i:]
-
- arch := os.Getenv("GOARCH")
- if arch == "" {
- fatalf("$GOARCH is not set")
- }
- ptrSize := ptrSizeMap[arch]
- if ptrSize == 0 {
- fatalf("unknown $GOARCH %q", arch)
- }
-
- // Clear locale variables so gcc emits English errors [sic].
- os.Setenv("LANG", "en_US.UTF-8")
- os.Setenv("LC_ALL", "C")
- os.Setenv("LC_CTYPE", "C")
-
- p := &Package{
- PtrSize: ptrSize,
- GccOptions: gccOptions,
- CgoFlags: make(map[string]string),
- Written: make(map[string]bool),
- }
-
- // Need a unique prefix for the global C symbols that
- // we use to coordinate between gcc and ourselves.
- // We already put _cgo_ at the beginning, so the main
- // concern is other cgo wrappers for the same functions.
- // Use the beginning of the md5 of the input to disambiguate.
- h := md5.New()
- for _, input := range goFiles {
- f, err := os.Open(input)
- if err != nil {
- fatalf("%s", err)
- }
- io.Copy(h, f)
- f.Close()
- }
- cPrefix = fmt.Sprintf("_%x", h.Sum()[0:6])
-
- fs := make([]*File, len(goFiles))
- for i, input := range goFiles {
- // Parse flags for all files before translating due to CFLAGS.
- f := new(File)
- f.ReadGo(input)
- p.ParseFlags(f, input)
- fs[i] = f
- }
-
- // make sure that _obj directory exists, so that we can write
- // all the output files there.
- os.Mkdir("_obj", 0777)
-
- for i, input := range goFiles {
- f := fs[i]
- p.Translate(f)
- for _, cref := range f.Ref {
- switch cref.Context {
- case "call", "call2":
- if cref.Name.Kind != "type" {
- break
- }
- *cref.Expr = cref.Name.Type.Go
- }
- }
- if nerrors > 0 {
- os.Exit(2)
- }
- pkg := f.Package
- if dir := os.Getenv("CGOPKGPATH"); dir != "" {
- pkg = filepath.Join(dir, pkg)
- }
- p.PackagePath = pkg
- p.writeOutput(f, input)
-
- p.Record(f)
- }
-
- p.writeDefs()
- if nerrors > 0 {
- os.Exit(2)
- }
-}
-
-// Record what needs to be recorded about f.
-func (p *Package) Record(f *File) {
- if p.PackageName == "" {
- p.PackageName = f.Package
- } else if p.PackageName != f.Package {
- error(token.NoPos, "inconsistent package names: %s, %s", p.PackageName, f.Package)
- }
-
- if p.Name == nil {
- p.Name = f.Name
- } else {
- for k, v := range f.Name {
- if p.Name[k] == nil {
- p.Name[k] = v
- } else if !reflect.DeepEqual(p.Name[k], v) {
- error(token.NoPos, "inconsistent definitions for C.%s", k)
- }
- }
- }
-
- p.ExpFunc = append(p.ExpFunc, f.ExpFunc...)
- p.Decl = append(p.Decl, f.AST.Decls...)
-}