github.com/slayercat/go@v0.0.0-20170428012452-c51559813f61/src/cmd/link/internal/ld/util.go (about)

     1  // Copyright 2015 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 ld
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/binary"
    10  	"fmt"
    11  	"os"
    12  	"strings"
    13  	"time"
    14  )
    15  
    16  var startTime time.Time
    17  
    18  // TODO(josharian): delete. See issue 19865.
    19  func Cputime() float64 {
    20  	if startTime.IsZero() {
    21  		startTime = time.Now()
    22  	}
    23  	return time.Since(startTime).Seconds()
    24  }
    25  
    26  func cstring(x []byte) string {
    27  	i := bytes.IndexByte(x, '\x00')
    28  	if i >= 0 {
    29  		x = x[:i]
    30  	}
    31  	return string(x)
    32  }
    33  
    34  func tokenize(s string) []string {
    35  	var f []string
    36  	for {
    37  		s = strings.TrimLeft(s, " \t\r\n")
    38  		if s == "" {
    39  			break
    40  		}
    41  		quote := false
    42  		i := 0
    43  		for ; i < len(s); i++ {
    44  			if s[i] == '\'' {
    45  				if quote && i+1 < len(s) && s[i+1] == '\'' {
    46  					i++
    47  					continue
    48  				}
    49  				quote = !quote
    50  			}
    51  			if !quote && (s[i] == ' ' || s[i] == '\t' || s[i] == '\r' || s[i] == '\n') {
    52  				break
    53  			}
    54  		}
    55  		next := s[:i]
    56  		s = s[i:]
    57  		if strings.Contains(next, "'") {
    58  			var buf []byte
    59  			quote := false
    60  			for i := 0; i < len(next); i++ {
    61  				if next[i] == '\'' {
    62  					if quote && i+1 < len(next) && next[i+1] == '\'' {
    63  						i++
    64  						buf = append(buf, '\'')
    65  					}
    66  					quote = !quote
    67  					continue
    68  				}
    69  				buf = append(buf, next[i])
    70  			}
    71  			next = string(buf)
    72  		}
    73  		f = append(f, next)
    74  	}
    75  	return f
    76  }
    77  
    78  var atExitFuncs []func()
    79  
    80  func AtExit(f func()) {
    81  	atExitFuncs = append(atExitFuncs, f)
    82  }
    83  
    84  // Exit exits with code after executing all atExitFuncs.
    85  func Exit(code int) {
    86  	for i := len(atExitFuncs) - 1; i >= 0; i-- {
    87  		atExitFuncs[i]()
    88  	}
    89  	os.Exit(code)
    90  }
    91  
    92  // Exitf logs an error message then calls Exit(2).
    93  func Exitf(format string, a ...interface{}) {
    94  	fmt.Fprintf(os.Stderr, os.Args[0]+": "+format+"\n", a...)
    95  	if coutbuf.f != nil {
    96  		coutbuf.f.Close()
    97  		mayberemoveoutfile()
    98  	}
    99  	Exit(2)
   100  }
   101  
   102  // Errorf logs an error message.
   103  //
   104  // If more than 20 errors have been printed, exit with an error.
   105  //
   106  // Logging an error means that on exit cmd/link will delete any
   107  // output file and return a non-zero error code.
   108  func Errorf(s *Symbol, format string, args ...interface{}) {
   109  	if s != nil {
   110  		format = s.Name + ": " + format
   111  	}
   112  	format += "\n"
   113  	fmt.Fprintf(os.Stderr, format, args...)
   114  	nerrors++
   115  	if *flagH {
   116  		panic("error")
   117  	}
   118  	if nerrors > 20 {
   119  		Exitf("too many errors")
   120  	}
   121  }
   122  
   123  func artrim(x []byte) string {
   124  	i := 0
   125  	j := len(x)
   126  	for i < len(x) && x[i] == ' ' {
   127  		i++
   128  	}
   129  	for j > i && x[j-1] == ' ' {
   130  		j--
   131  	}
   132  	return string(x[i:j])
   133  }
   134  
   135  func stringtouint32(x []uint32, s string) {
   136  	for i := 0; len(s) > 0; i++ {
   137  		var buf [4]byte
   138  		s = s[copy(buf[:], s):]
   139  		x[i] = binary.LittleEndian.Uint32(buf[:])
   140  	}
   141  }
   142  
   143  var start = time.Now()
   144  
   145  func elapsed() float64 {
   146  	return time.Since(start).Seconds()
   147  }