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