gen_header.py 2.1 KB
Newer Older
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
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import argparse
import sys
import subprocess

MAGIC = 'midout_trace v1\n'

class MidoutHeaderGen:
    _tag_names = None
    _region_names = None

    def __init__(self):
        self._tag_names = set()
        self._region_names = set()

    def add_item(self, name: str):
        prefix = 'midout::Region<midout::tags::'
        assert name.startswith(prefix), 'bad name: {!r}'.format(name)
        comma = name.find(',', len(prefix))
        self._tag_names.add(name[len(prefix):comma])
        self._region_names.add(name)

    def write(self, fout):
        print('#define MIDOUT_GENERATED \\', file=fout)
        print('namespace midout { namespace tags { \\', file=fout)
        for i in sorted(self._tag_names):
            print('class {}; \\'.format(i), file=fout)
        print('} \\', file=fout)

        for i in self._region_names:
            i = i.replace('midout::', '')
            i = i.replace('__ndk1::', '')
            print('template<> \\', file=fout)
            print('struct {} {{ static constexpr bool enable = true; }}; \\'.
                  format(i), file=fout)

        print('}', file=fout)


def main():
    parser = argparse.ArgumentParser(
        description='generate header file from midout traces',
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('-o', '--output',
                        help='output header file; default to stdout')
    parser.add_argument('inputs', nargs='+', help='input trace files')
    args = parser.parse_args()
    gen = MidoutHeaderGen()
    for i in args.inputs:
        with open(i) as fin:
            assert fin.read(len(MAGIC)) == MAGIC, 'bad trace file'
            demangle = subprocess.check_output(
                ['c++filt', '-t'], input='\n'.join(list(fin)).encode('utf-8'))
            for line in demangle.decode('utf-8').split('\n'):
                line = line.strip()
                if line:
                    gen.add_item(line)

    if not args.output:
        gen.write(sys.stdout)
    else:
        with open(args.output, 'w') as fout:
            gen.write(fout)

if __name__ == '__main__':
    main()