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