Home | History | Annotate | Download | only in ld
      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 }
    138