github.com/seh/gb@v0.4.4-0.20160724065125-065d2b2b1ba1/internal/importer/build.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package importer 6 7 import ( 8 "bytes" 9 "fmt" 10 "go/token" 11 "path/filepath" 12 "strings" 13 ) 14 15 // importer is a private interface defined here so public *Importer 16 // types can be embedded in *Package with exposing them to the caller. 17 type importer interface { 18 matchFile(path string, allTags map[string]bool) (match bool, data []byte, err error) 19 match(name string, allTags map[string]bool) bool 20 } 21 22 // A Package describes the Go package found in a directory. 23 type Package struct { 24 importer // the importer context that loaded this package 25 Dir string // directory containing package sources 26 Name string // package name 27 ImportPath string // import path of package ("" if unknown) 28 Root string // root of Go tree where this package lives 29 SrcRoot string // package source root directory ("" if unknown) 30 PkgTargetRoot string // architecture dependent install root directory ("" if unknown) 31 Standard bool // package found in GOROOT 32 AllTags []string // tags that can influence file selection in this directory 33 ConflictDir string // this directory shadows Dir in $GOPATH 34 35 // Source files 36 GoFiles []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) 37 CgoFiles []string // .go source files that import "C" 38 IgnoredGoFiles []string // .go source files ignored for this build 39 CFiles []string // .c source files 40 CXXFiles []string // .cc, .cpp and .cxx source files 41 MFiles []string // .m (Objective-C) source files 42 HFiles []string // .h, .hh, .hpp and .hxx source files 43 SFiles []string // .s source files 44 SwigFiles []string // .swig files 45 SwigCXXFiles []string // .swigcxx files 46 SysoFiles []string // .syso system object files to add to archive 47 48 // Cgo directives 49 CgoCFLAGS []string // Cgo CFLAGS directives 50 CgoCPPFLAGS []string // Cgo CPPFLAGS directives 51 CgoCXXFLAGS []string // Cgo CXXFLAGS directives 52 CgoLDFLAGS []string // Cgo LDFLAGS directives 53 CgoPkgConfig []string // Cgo pkg-config directives 54 55 // Dependency information 56 Imports []string // imports from GoFiles, CgoFiles 57 ImportPos map[string][]token.Position // line information for Imports 58 59 // Test information 60 TestGoFiles []string // _test.go files in package 61 TestImports []string // imports from TestGoFiles 62 TestImportPos map[string][]token.Position // line information for TestImports 63 XTestGoFiles []string // _test.go files outside package 64 XTestImports []string // imports from XTestGoFiles 65 XTestImportPos map[string][]token.Position // line information for XTestImports 66 } 67 68 // NoGoError is the error used by Import to describe a directory 69 // containing no buildable Go source files. (It may still contain 70 // test files, files hidden by build tags, and so on.) 71 type NoGoError struct { 72 Dir string 73 } 74 75 func (e *NoGoError) Error() string { 76 return "no buildable Go source files in " + e.Dir 77 } 78 79 // MultiplePackageError describes a directory containing 80 // multiple buildable Go source files for multiple packages. 81 type MultiplePackageError struct { 82 Dir string // directory containing files 83 Packages []string // package names found 84 Files []string // corresponding files: Files[i] declares package Packages[i] 85 } 86 87 func (e *MultiplePackageError) Error() string { 88 // Error string limited to two entries for compatibility. 89 return fmt.Sprintf("found packages %s (%s) and %s (%s) in %s", e.Packages[0], e.Files[0], e.Packages[1], e.Files[1], e.Dir) 90 } 91 92 // expandSrcDir expands any occurrence of ${SRCDIR}, making sure 93 // the result is safe for the shell. 94 func expandSrcDir(str string, srcdir string) (string, bool) { 95 // "\" delimited paths cause safeCgoName to fail 96 // so convert native paths with a different delimeter 97 // to "/" before starting (eg: on windows). 98 srcdir = filepath.ToSlash(srcdir) 99 100 // Spaces are tolerated in ${SRCDIR}, but not anywhere else. 101 chunks := strings.Split(str, "${SRCDIR}") 102 if len(chunks) < 2 { 103 return str, safeCgoName(str, false) 104 } 105 ok := true 106 for _, chunk := range chunks { 107 ok = ok && (chunk == "" || safeCgoName(chunk, false)) 108 } 109 ok = ok && (srcdir == "" || safeCgoName(srcdir, true)) 110 res := strings.Join(chunks, srcdir) 111 return res, ok && res != "" 112 } 113 114 // NOTE: $ is not safe for the shell, but it is allowed here because of linker options like -Wl,$ORIGIN. 115 // We never pass these arguments to a shell (just to programs we construct argv for), so this should be okay. 116 // See golang.org/issue/6038. 117 const safeString = "+-.,/0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz:$" 118 const safeSpaces = " " 119 120 var safeBytes = []byte(safeSpaces + safeString) 121 122 func safeCgoName(s string, spaces bool) bool { 123 if s == "" { 124 return false 125 } 126 safe := safeBytes 127 if !spaces { 128 safe = safe[len(safeSpaces):] 129 } 130 for i := 0; i < len(s); i++ { 131 if c := s[i]; c < 0x80 && bytes.IndexByte(safe, c) < 0 { 132 return false 133 } 134 } 135 return true 136 }