github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/cmd/internal/objabi/line.go (about) 1 // Copyright 2009 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 objabi 6 7 import ( 8 "os" 9 "path/filepath" 10 ) 11 12 // WorkingDir returns the current working directory 13 // (or "/???" if the directory cannot be identified), 14 // with "/" as separator. 15 func WorkingDir() string { 16 var path string 17 path, _ = os.Getwd() 18 if path == "" { 19 path = "/???" 20 } 21 return filepath.ToSlash(path) 22 } 23 24 // AbsFile returns the absolute filename for file in the given directory. 25 // It also removes a leading pathPrefix, or else rewrites a leading $GOROOT 26 // prefix to the literal "$GOROOT". 27 // If the resulting path is the empty string, the result is "??". 28 func AbsFile(dir, file, pathPrefix string) string { 29 abs := file 30 if dir != "" && !filepath.IsAbs(file) { 31 abs = filepath.Join(dir, file) 32 } 33 34 if pathPrefix != "" && hasPathPrefix(abs, pathPrefix) { 35 if abs == pathPrefix { 36 abs = "" 37 } else { 38 abs = abs[len(pathPrefix)+1:] 39 } 40 } else if hasPathPrefix(abs, GOROOT) { 41 abs = "$GOROOT" + abs[len(GOROOT):] 42 } 43 if abs == "" { 44 abs = "??" 45 } 46 47 return abs 48 } 49 50 // Does s have t as a path prefix? 51 // That is, does s == t or does s begin with t followed by a slash? 52 // For portability, we allow ASCII case folding, so that hasPathPrefix("a/b/c", "A/B") is true. 53 // Similarly, we allow slash folding, so that hasPathPrefix("a/b/c", "a\\b") is true. 54 // We do not allow full Unicode case folding, for fear of causing more confusion 55 // or harm than good. (For an example of the kinds of things that can go wrong, 56 // see http://article.gmane.org/gmane.linux.kernel/1853266.) 57 func hasPathPrefix(s string, t string) bool { 58 if len(t) > len(s) { 59 return false 60 } 61 var i int 62 for i = 0; i < len(t); i++ { 63 cs := int(s[i]) 64 ct := int(t[i]) 65 if 'A' <= cs && cs <= 'Z' { 66 cs += 'a' - 'A' 67 } 68 if 'A' <= ct && ct <= 'Z' { 69 ct += 'a' - 'A' 70 } 71 if cs == '\\' { 72 cs = '/' 73 } 74 if ct == '\\' { 75 ct = '/' 76 } 77 if cs != ct { 78 return false 79 } 80 } 81 return i >= len(s) || s[i] == '/' || s[i] == '\\' 82 }