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