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 	"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