github.com/tidwall/go@v0.0.0-20170415222209-6694a6888b7d/src/cmd/internal/obj/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 obj
     6  
     7  import (
     8  	"cmd/internal/src"
     9  	"path/filepath"
    10  )
    11  
    12  // AbsFile returns the absolute filename for file in the given directory.
    13  // It also removes a leading pathPrefix, or else rewrites a leading $GOROOT
    14  // prefix to the literal "$GOROOT".
    15  // If the resulting path is the empty string, the result is "??".
    16  func AbsFile(dir, file, pathPrefix string) string {
    17  	abs := file
    18  	if dir != "" && !filepath.IsAbs(file) {
    19  		abs = filepath.Join(dir, file)
    20  	}
    21  
    22  	if pathPrefix != "" && hasPathPrefix(abs, pathPrefix) {
    23  		if abs == pathPrefix {
    24  			abs = ""
    25  		} else {
    26  			abs = abs[len(pathPrefix)+1:]
    27  		}
    28  	} else if hasPathPrefix(abs, GOROOT) {
    29  		abs = "$GOROOT" + abs[len(GOROOT):]
    30  	}
    31  	if abs == "" {
    32  		abs = "??"
    33  	}
    34  
    35  	return filepath.Clean(abs)
    36  }
    37  
    38  // Does s have t as a path prefix?
    39  // That is, does s == t or does s begin with t followed by a slash?
    40  // For portability, we allow ASCII case folding, so that hasPathPrefix("a/b/c", "A/B") is true.
    41  // Similarly, we allow slash folding, so that hasPathPrefix("a/b/c", "a\\b") is true.
    42  // We do not allow full Unicode case folding, for fear of causing more confusion
    43  // or harm than good. (For an example of the kinds of things that can go wrong,
    44  // see http://article.gmane.org/gmane.linux.kernel/1853266.)
    45  func hasPathPrefix(s string, t string) bool {
    46  	if len(t) > len(s) {
    47  		return false
    48  	}
    49  	var i int
    50  	for i = 0; i < len(t); i++ {
    51  		cs := int(s[i])
    52  		ct := int(t[i])
    53  		if 'A' <= cs && cs <= 'Z' {
    54  			cs += 'a' - 'A'
    55  		}
    56  		if 'A' <= ct && ct <= 'Z' {
    57  			ct += 'a' - 'A'
    58  		}
    59  		if cs == '\\' {
    60  			cs = '/'
    61  		}
    62  		if ct == '\\' {
    63  			ct = '/'
    64  		}
    65  		if cs != ct {
    66  			return false
    67  		}
    68  	}
    69  	return i >= len(s) || s[i] == '/' || s[i] == '\\'
    70  }
    71  
    72  // AddImport adds a package to the list of imported packages.
    73  func (ctxt *Link) AddImport(pkg string) {
    74  	ctxt.Imports = append(ctxt.Imports, pkg)
    75  }
    76  
    77  func linkgetlineFromPos(ctxt *Link, xpos src.XPos) (f string, l int32) {
    78  	pos := ctxt.PosTable.Pos(xpos)
    79  	if !pos.IsKnown() {
    80  		pos = src.Pos{}
    81  	}
    82  	// TODO(gri) Should this use relative or absolute line number?
    83  	return pos.SymFilename(), int32(pos.RelLine())
    84  }