github.com/rakyll/go@v0.0.0-20170216000551-64c02460d703/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 *LSym, l int32) {
    78  	pos := ctxt.PosTable.Pos(xpos)
    79  	filename := pos.AbsFilename()
    80  	if !pos.IsKnown() || filename == "" {
    81  		return Linklookup(ctxt, "??", HistVersion), 0
    82  	}
    83  	// TODO(gri) Should this use relative or absolute line number?
    84  	return Linklookup(ctxt, filename, HistVersion), int32(pos.RelLine())
    85  }
    86  
    87  func fieldtrack(ctxt *Link, cursym *LSym) {
    88  	p := cursym.Text
    89  	if p == nil || p.Link == nil { // handle external functions and ELF section symbols
    90  		return
    91  	}
    92  	ctxt.Cursym = cursym
    93  
    94  	for ; p != nil; p = p.Link {
    95  		if p.As == AUSEFIELD {
    96  			r := Addrel(ctxt.Cursym)
    97  			r.Off = 0
    98  			r.Siz = 0
    99  			r.Sym = p.From.Sym
   100  			r.Type = R_USEFIELD
   101  		}
   102  	}
   103  }