github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/src/cmd/link/hex_test.go (about)

     1  // Copyright 2014 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 main
     6  
     7  import (
     8  	"encoding/hex"
     9  	"fmt"
    10  	"io/ioutil"
    11  	"regexp"
    12  	"strconv"
    13  	"strings"
    14  	"testing"
    15  )
    16  
    17  // mustParseHexdumpFile returns a block of data generated by
    18  // parsing the hex dump in the named file.
    19  // If the file cannot be read or does not contain a valid hex dump,
    20  // mustParseHexdumpFile calls t.Fatal.
    21  func mustParseHexdumpFile(t *testing.T, file string) []byte {
    22  	hex, err := ioutil.ReadFile(file)
    23  	if err != nil {
    24  		t.Fatal(err)
    25  	}
    26  	data, err := parseHexdump(string(hex))
    27  	if err != nil {
    28  		t.Fatal(err)
    29  	}
    30  	return data
    31  }
    32  
    33  // parseHexdump parses the hex dump in text, which should be the
    34  // output of "hexdump -C" or Plan 9's "xd -b",
    35  // and returns the original data used to produce the dump.
    36  // It is meant to enable storing golden binary files as text, so that
    37  // changes to the golden files can be seen during code reviews.
    38  func parseHexdump(text string) ([]byte, error) {
    39  	var out []byte
    40  	for _, line := range strings.Split(text, "\n") {
    41  		if i := strings.Index(line, "|"); i >= 0 { // remove text dump
    42  			line = line[:i]
    43  		}
    44  		f := strings.Fields(line)
    45  		if len(f) > 1+16 {
    46  			return nil, fmt.Errorf("parsing hex dump: too many fields on line %q", line)
    47  		}
    48  		if len(f) == 0 || len(f) == 1 && f[0] == "*" { // all zeros block omitted
    49  			continue
    50  		}
    51  		addr64, err := strconv.ParseUint(f[0], 16, 0)
    52  		if err != nil {
    53  			return nil, fmt.Errorf("parsing hex dump: invalid address %q", f[0])
    54  		}
    55  		addr := int(addr64)
    56  		if len(out) < addr {
    57  			out = append(out, make([]byte, addr-len(out))...)
    58  		}
    59  		for _, x := range f[1:] {
    60  			val, err := strconv.ParseUint(x, 16, 8)
    61  			if err != nil {
    62  				return nil, fmt.Errorf("parsing hexdump: invalid hex byte %q", x)
    63  			}
    64  			out = append(out, byte(val))
    65  		}
    66  	}
    67  	return out, nil
    68  }
    69  
    70  func hexdump(data []byte) string {
    71  	text := hex.Dump(data) + fmt.Sprintf("%08x\n", len(data))
    72  	text = regexp.MustCompile(`\n([0-9a-f]+(\s+00){16}.*\n)+`).ReplaceAllString(text, "\n*\n")
    73  	return text
    74  }