1#!/usr/bin/env python 2 3import sys, os, os.path as path, struct, errno 4from optparse import OptionParser 5 6def xencov_split(opts): 7 """Split input into multiple gcda files""" 8 9 # Check native byte order and explicitly specify it. The "native" 10 # byte order in struct module takes into account padding while the 11 # data is always packed. 12 if sys.byteorder == 'little': 13 bo_prefix = '<' 14 else: 15 bo_prefix = '>' 16 17 input_file = opts.args[0] 18 19 f = open(input_file) 20 21 # Magic number 22 s = f.read(4) 23 magic, = struct.unpack(bo_prefix + "I", s) 24 # See public/sysctl.h for magic number -- "XCOV" 25 if magic != 0x58434f56: 26 raise Exception("Invalid magic number") 27 28 # The rest is zero or more records 29 content = f.read() 30 31 f.close() 32 33 while content: 34 off = content.find('\x00') 35 fmt = bo_prefix + str(off) + 's' 36 fn, = struct.unpack_from(fmt, content) 37 content = content[off+1:] 38 39 fmt = bo_prefix + 'I' 40 sz, = struct.unpack_from(fmt, content) 41 content = content[struct.calcsize(fmt):] 42 43 fmt = bo_prefix + str(sz) + 's' 44 payload, = struct.unpack_from(fmt, content) 45 content = content[sz:] 46 47 # Create and store files 48 if opts.output_dir == '.': 49 opts.output_dir = os.getcwd() 50 51 dir = opts.output_dir + path.dirname(fn) 52 try: 53 os.makedirs(dir) 54 except OSError, e: 55 if e.errno == errno.EEXIST and os.path.isdir(dir): 56 pass 57 else: 58 raise 59 60 full_path = dir + '/' + path.basename(fn) 61 f = open(full_path, "w") 62 f.write(payload) 63 f.close() 64 65def main(): 66 """ Main entrypoint """ 67 68 # Change stdout to be line-buffered. 69 sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 1) 70 71 parser = OptionParser( 72 usage = "%prog [OPTIONS] <INPUT>", 73 description = "Utility to split xencov data file", 74 ) 75 76 parser.add_option("--output-dir", action = "store", 77 dest = "output_dir", default = ".", 78 type = "string", 79 help = ('Specify the directory to place output files, ' 80 'defaults to current directory'), 81 ) 82 83 opts, args = parser.parse_args() 84 opts.args = args 85 86 xencov_split(opts) 87 88 89if __name__ == "__main__": 90 try: 91 sys.exit(main()) 92 except Exception, e: 93 print >>sys.stderr, "Error:", e 94 sys.exit(1) 95 except KeyboardInterrupt: 96 sys.exit(1) 97 98