about summary refs log tree commit diff homepage
path: root/tools/ktest-tool/ktest-tool
blob: b7504be842ad26b67cdca2f83e9bbbf8f6f6a83f (plain) (blame)
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
#!/usr/bin/env python

import os
import struct
import sys

version_no=3

class KTestError(Exception):
    pass

class KTest:
    @staticmethod
    def fromfile(path):
        if not os.path.exists(path):
            print("ERROR: file %s not found" % (path))
            sys.exit(1)
            
        f = open(path,'rb')
        hdr = f.read(5)
        if len(hdr)!=5 or (hdr!=b'KTEST' and hdr != b"BOUT\n"):
            raise KTestError('unrecognized file')
        version, = struct.unpack('>i', f.read(4))
        if version > version_no:
            raise KTestError('unrecognized version')
        numArgs, = struct.unpack('>i', f.read(4))
        args = []
        for i in range(numArgs):
            size, = struct.unpack('>i', f.read(4))
            args.append(str(f.read(size).decode(encoding='ascii')))
            
        if version >= 2:
            symArgvs, = struct.unpack('>i', f.read(4))
            symArgvLen, = struct.unpack('>i', f.read(4))
        else:
            symArgvs = 0
            symArgvLen = 0

        numObjects, = struct.unpack('>i', f.read(4))
        objects = []
        for i in range(numObjects):
            size, = struct.unpack('>i', f.read(4))
            name = f.read(size)
            size, = struct.unpack('>i', f.read(4))
            bytes = f.read(size)
            objects.append( (name,bytes) )

        # Create an instance
        b = KTest(version, args, symArgvs, symArgvLen, objects)
        # Augment with extra filename field
        b.filename = path
        return b
    
    def __init__(self, version, args, symArgvs, symArgvLen, objects):
        self.version = version
        self.symArgvs = symArgvs
        self.symArgvLen = symArgvLen
        self.args = args
        self.objects = objects

        # add a field that represents the name of the program used to
        # generate this .ktest file:
        program_full_path = self.args[0]
        program_name = os.path.basename(program_full_path)
        # sometimes program names end in .bc, so strip them
        if program_name.endswith('.bc'):
          program_name = program_name[:-3]
        self.programName = program_name
        
def trimZeros(str):
    for i in range(len(str))[::-1]:
        if str[i] != '\x00':
            return str[:i+1]
    return ''
    
def main(args):
    from optparse import OptionParser
    op = OptionParser("usage: %prog [options] files")
    op.add_option('','--trim-zeros', dest='trimZeros', action='store_true', 
                  default=False,
                  help='trim trailing zeros')
    op.add_option('','--write-ints', dest='writeInts', action='store_true',
                  default=False,
                  help='convert 4-byte sequences to integers')
    
    opts,args = op.parse_args()
    if not args:
        op.error("incorrect number of arguments")

    for file in args:
        b = KTest.fromfile(file)
        pos = 0
        print('ktest file : %r' % file)
        print('args       : %r' % b.args)
        print('num objects: %r' % len(b.objects))
        for i,(name,data) in enumerate(b.objects):
            if opts.trimZeros:
                str = trimZeros(data)
            else:
                str = data

            print('object %4d: name: %r' % (i, name))
            print('object %4d: size: %r' % (i, len(data)))
            if opts.writeInts and len(data) == 4: 
                print('object %4d: data: %r' % (i, struct.unpack('i',str)[0]))
            else:
                print('object %4d: data: %r' % (i, str))
        if file != args[-1]:
            print()

if __name__=='__main__':
    main(sys.argv)