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