1*1ef08e34SPierrick Bouvier#!/usr/bin/env python3 2*1ef08e34SPierrick Bouvier# -*- coding: utf-8 -*- 3*1ef08e34SPierrick Bouvier# 4*1ef08e34SPierrick Bouvier# Extract QEMU Plugin API symbols from a header file 5*1ef08e34SPierrick Bouvier# 6*1ef08e34SPierrick Bouvier# Copyright 2024 Linaro Ltd 7*1ef08e34SPierrick Bouvier# 8*1ef08e34SPierrick Bouvier# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org> 9*1ef08e34SPierrick Bouvier# 10*1ef08e34SPierrick Bouvier# This work is licensed under the terms of the GNU GPL, version 2 or later. 11*1ef08e34SPierrick Bouvier# See the COPYING file in the top-level directory. 12*1ef08e34SPierrick Bouvier# 13*1ef08e34SPierrick Bouvier# SPDX-License-Identifier: GPL-2.0-or-later 14*1ef08e34SPierrick Bouvier 15*1ef08e34SPierrick Bouvierimport argparse 16*1ef08e34SPierrick Bouvierimport re 17*1ef08e34SPierrick Bouvier 18*1ef08e34SPierrick Bouvierdef extract_symbols(plugin_header): 19*1ef08e34SPierrick Bouvier with open(plugin_header) as file: 20*1ef08e34SPierrick Bouvier content = file.read() 21*1ef08e34SPierrick Bouvier # Remove QEMU_PLUGIN_API macro definition. 22*1ef08e34SPierrick Bouvier content = content.replace('#define QEMU_PLUGIN_API', '') 23*1ef08e34SPierrick Bouvier expected = content.count('QEMU_PLUGIN_API') 24*1ef08e34SPierrick Bouvier # Find last word between QEMU_PLUGIN_API and (, matching on several lines. 25*1ef08e34SPierrick Bouvier # We use *? non-greedy quantifier. 26*1ef08e34SPierrick Bouvier syms = re.findall(r'QEMU_PLUGIN_API.*?(\w+)\s*\(', content, re.DOTALL) 27*1ef08e34SPierrick Bouvier syms.sort() 28*1ef08e34SPierrick Bouvier # Ensure we found as many symbols as API markers. 29*1ef08e34SPierrick Bouvier assert len(syms) == expected 30*1ef08e34SPierrick Bouvier return syms 31*1ef08e34SPierrick Bouvier 32*1ef08e34SPierrick Bouvierdef main() -> None: 33*1ef08e34SPierrick Bouvier parser = argparse.ArgumentParser(description='Extract QEMU plugin symbols') 34*1ef08e34SPierrick Bouvier parser.add_argument('plugin_header', help='Path to QEMU plugin header.') 35*1ef08e34SPierrick Bouvier args = parser.parse_args() 36*1ef08e34SPierrick Bouvier 37*1ef08e34SPierrick Bouvier syms = extract_symbols(args.plugin_header) 38*1ef08e34SPierrick Bouvier 39*1ef08e34SPierrick Bouvier print('{') 40*1ef08e34SPierrick Bouvier for s in syms: 41*1ef08e34SPierrick Bouvier print(" {};".format(s)) 42*1ef08e34SPierrick Bouvier print('};') 43*1ef08e34SPierrick Bouvier 44*1ef08e34SPierrick Bouvierif __name__ == '__main__': 45*1ef08e34SPierrick Bouvier main() 46