github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/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 }