Philippe Mathieu-Daudé | 5aa6280 | 2020-05-12 12:32:37 +0200 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
Marc Mari | 0c0c1fd | 2016-08-12 09:27:02 -0400 | [diff] [blame] | 2 | # |
| 3 | # Module information generator |
| 4 | # |
| 5 | # Copyright Red Hat, Inc. 2015 - 2016 |
| 6 | # |
| 7 | # Authors: |
| 8 | # Marc Mari <markmb@redhat.com> |
| 9 | # |
| 10 | # This work is licensed under the terms of the GNU GPL, version 2. |
| 11 | # See the COPYING file in the top-level directory. |
| 12 | |
Marc Mari | 0c0c1fd | 2016-08-12 09:27:02 -0400 | [diff] [blame] | 13 | import sys |
| 14 | import os |
| 15 | |
| 16 | def get_string_struct(line): |
| 17 | data = line.split() |
| 18 | |
| 19 | # data[0] -> struct element name |
| 20 | # data[1] -> = |
| 21 | # data[2] -> value |
| 22 | |
| 23 | return data[2].replace('"', '')[:-1] |
| 24 | |
| 25 | def add_module(fheader, library, format_name, protocol_name): |
| 26 | lines = [] |
| 27 | lines.append('.library_name = "' + library + '",') |
| 28 | if format_name != "": |
| 29 | lines.append('.format_name = "' + format_name + '",') |
| 30 | if protocol_name != "": |
| 31 | lines.append('.protocol_name = "' + protocol_name + '",') |
| 32 | |
| 33 | text = '\n '.join(lines) |
| 34 | fheader.write('\n {\n ' + text + '\n },') |
| 35 | |
| 36 | def process_file(fheader, filename): |
| 37 | # This parser assumes the coding style rules are being followed |
| 38 | with open(filename, "r") as cfile: |
Marc Mari | 0c0c1fd | 2016-08-12 09:27:02 -0400 | [diff] [blame] | 39 | found_start = False |
| 40 | library, _ = os.path.splitext(os.path.basename(filename)) |
| 41 | for line in cfile: |
| 42 | if found_start: |
| 43 | line = line.replace('\n', '') |
| 44 | if line.find(".format_name") != -1: |
| 45 | format_name = get_string_struct(line) |
| 46 | elif line.find(".protocol_name") != -1: |
| 47 | protocol_name = get_string_struct(line) |
| 48 | elif line == "};": |
| 49 | add_module(fheader, library, format_name, protocol_name) |
| 50 | found_start = False |
| 51 | elif line.find("static BlockDriver") != -1: |
Marc Mari | 0c0c1fd | 2016-08-12 09:27:02 -0400 | [diff] [blame] | 52 | found_start = True |
| 53 | format_name = "" |
| 54 | protocol_name = "" |
| 55 | |
Marc Mari | 0c0c1fd | 2016-08-12 09:27:02 -0400 | [diff] [blame] | 56 | def print_top(fheader): |
| 57 | fheader.write('''/* AUTOMATICALLY GENERATED, DO NOT MODIFY */ |
| 58 | /* |
| 59 | * QEMU Block Module Infrastructure |
| 60 | * |
| 61 | * Authors: |
| 62 | * Marc Mari <markmb@redhat.com> |
| 63 | */ |
| 64 | |
| 65 | ''') |
| 66 | |
| 67 | fheader.write('''#ifndef QEMU_MODULE_BLOCK_H |
| 68 | #define QEMU_MODULE_BLOCK_H |
| 69 | |
Marc Mari | 0c0c1fd | 2016-08-12 09:27:02 -0400 | [diff] [blame] | 70 | static const struct { |
| 71 | const char *format_name; |
| 72 | const char *protocol_name; |
| 73 | const char *library_name; |
| 74 | } block_driver_modules[] = {''') |
| 75 | |
| 76 | def print_bottom(fheader): |
| 77 | fheader.write(''' |
| 78 | }; |
| 79 | |
| 80 | #endif |
| 81 | ''') |
| 82 | |
Philippe Mathieu-Daudé | 5aa6280 | 2020-05-12 12:32:37 +0200 | [diff] [blame] | 83 | if __name__ == '__main__': |
| 84 | # First argument: output file |
| 85 | # All other arguments: modules source files (.c) |
| 86 | output_file = sys.argv[1] |
| 87 | with open(output_file, 'w') as fheader: |
| 88 | print_top(fheader) |
Marc Mari | 0c0c1fd | 2016-08-12 09:27:02 -0400 | [diff] [blame] | 89 | |
Philippe Mathieu-Daudé | 5aa6280 | 2020-05-12 12:32:37 +0200 | [diff] [blame] | 90 | for filename in sys.argv[2:]: |
| 91 | if os.path.isfile(filename): |
| 92 | process_file(fheader, filename) |
| 93 | else: |
| 94 | print("File " + filename + " does not exist.", file=sys.stderr) |
| 95 | sys.exit(1) |
Marc Mari | 0c0c1fd | 2016-08-12 09:27:02 -0400 | [diff] [blame] | 96 | |
Philippe Mathieu-Daudé | 5aa6280 | 2020-05-12 12:32:37 +0200 | [diff] [blame] | 97 | print_bottom(fheader) |
Marc Mari | 0c0c1fd | 2016-08-12 09:27:02 -0400 | [diff] [blame] | 98 | |
Philippe Mathieu-Daudé | 5aa6280 | 2020-05-12 12:32:37 +0200 | [diff] [blame] | 99 | sys.exit(0) |