1#!/usr/bin/python
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
13from __future__ import print_function
14import sys
15import os
16
17def get_string_struct(line):
18    data = line.split()
19
20    # data[0] -> struct element name
21    # data[1] -> =
22    # data[2] -> value
23
24    return data[2].replace('"', '')[:-1]
25
26def add_module(fheader, library, format_name, protocol_name):
27    lines = []
28    lines.append('.library_name = "' + library + '",')
29    if format_name != "":
30        lines.append('.format_name = "' + format_name + '",')
31    if protocol_name != "":
32        lines.append('.protocol_name = "' + protocol_name + '",')
33
34    text = '\n        '.join(lines)
35    fheader.write('\n    {\n        ' + text + '\n    },')
36
37def process_file(fheader, filename):
38    # This parser assumes the coding style rules are being followed
39    with open(filename, "r") as cfile:
40        found_something = False
41        found_start = False
42        library, _ = os.path.splitext(os.path.basename(filename))
43        for line in cfile:
44            if found_start:
45                line = line.replace('\n', '')
46                if line.find(".format_name") != -1:
47                    format_name = get_string_struct(line)
48                elif line.find(".protocol_name") != -1:
49                    protocol_name = get_string_struct(line)
50                elif line == "};":
51                    add_module(fheader, library, format_name, protocol_name)
52                    found_start = False
53            elif line.find("static BlockDriver") != -1:
54                found_something = True
55                found_start = True
56                format_name = ""
57                protocol_name = ""
58
59        if not found_something:
60            print("No BlockDriver struct found in " + filename + ". \
61                    Is this really a module?", file=sys.stderr)
62            sys.exit(1)
63
64def print_top(fheader):
65    fheader.write('''/* AUTOMATICALLY GENERATED, DO NOT MODIFY */
66/*
67 * QEMU Block Module Infrastructure
68 *
69 * Authors:
70 *  Marc Mari       <markmb@redhat.com>
71 */
72
73''')
74
75    fheader.write('''#ifndef QEMU_MODULE_BLOCK_H
76#define QEMU_MODULE_BLOCK_H
77
78#include "qemu-common.h"
79
80static const struct {
81    const char *format_name;
82    const char *protocol_name;
83    const char *library_name;
84} block_driver_modules[] = {''')
85
86def print_bottom(fheader):
87    fheader.write('''
88};
89
90#endif
91''')
92
93# First argument: output file
94# All other arguments: modules source files (.c)
95output_file = sys.argv[1]
96with open(output_file, 'w') as fheader:
97    print_top(fheader)
98
99    for filename in sys.argv[2:]:
100        if os.path.isfile(filename):
101            process_file(fheader, filename)
102        else:
103            print("File " + filename + " does not exist.", file=sys.stderr)
104            sys.exit(1)
105
106    print_bottom(fheader)
107
108sys.exit(0)
109