~christof-mroz/hipl/hipfw-performance

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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
#!/usr/bin/python
import getopt, glob, os, sys, xml.dom.minidom

### Constants ###
APPLICATION_TAG_NAME  = 'application'
APPLICATION_ATTR_NAME = 'name'
APPLICATION_PATH_NAME = 'path'

MODULES_DIR      = 'modules'
MODULE_INFO_FILE = 'module_info.xml'

HEADER_FILE_DIR    = MODULES_DIR
HEADER_FILE_SUFFIX = '_modules.h'

WARNING_STRING = 'WARNING This file was generated by ' + __file__ + ' - '
WARNING_STRING += 'DO NOT EDIT!'

# Parses the XML document at 'path' and returns a dictionary with module info
def parse_xml_info(path):

    file = open(path, "r")
    dom = xml.dom.minidom.parse(file)
    file.close()

    module_info = {}

    module_name = str(dom.getElementsByTagName('module')[0].attributes['name'].value)
    module_info['version'] = str(dom.getElementsByTagName('module')[0].attributes['version'].value)

    module_info['requires'] = []
    if 0 < len(dom.getElementsByTagName('requires')):
        for node in dom.getElementsByTagName('requires')[0].getElementsByTagName('module'):
            current_req = {}
            current_req['name'] = str(node.attributes['name'].value)
            if 'minversion' in node.attributes.keys():
                current_req['minversion'] = str(node.attributes['minversion'].value)
            if 'maxversion' in node.attributes.keys():
                current_req['maxversion'] = str(node.attributes['maxversion'].value)

            module_info['requires'].append(current_req)

    module_info['conflicts'] = []
    if 0 < len(dom.getElementsByTagName('conflicts')):
        for node in dom.getElementsByTagName('conflicts')[0].getElementsByTagName('module'):
            current_con = {}
            current_con['name'] = str(node.attributes['name'].value)
            if 'minversion' in node.attributes.keys():
                current_con['minversion'] = str(node.attributes['minversion'].value)
            if 'maxversion' in node.attributes.keys():
                current_con['maxversion'] = str(node.attributes['maxversion'].value)

            module_info['conflicts'].append(current_con)

    module_info['application'] = {}
    if 0 == len(dom.getElementsByTagName('application')):
        print '|\n|    WARNING in configuration of ' + module_name + ':',
        print 'no application tag found'
        print '|    Please check configuration file'
        raise Error()

    for current_app in dom.getElementsByTagName('application'):
        app_info = {}
        name = str(current_app.attributes['name'].value)
        app_info['header_file'] = str(current_app.attributes['header_file'].value)
        app_info['init_function'] = str(current_app.attributes['init_function'].value)
        module_info['application'][name] = app_info

    return (module_name, module_info)

# Tries to read the XML configuration files for all sub-folders in the given
# directory and returns a dictionary containing the module information
def read_module_info(MODULES_DIR, disabled_modules):

    # Initialize output variable
    module_info = {}

    # Iterate through all sub directories in MODULES_DIR
    for current_module in glob.glob(MODULES_DIR + '/*/'):
        cont = False
        print '|    found module: ' + current_module
        # Check if current_module is disabled
        for disabled in disabled_modules:
            if current_module == os.path.join(MODULES_DIR, disabled) + '/':
                cont = True
                print '|    state:        ' + 'DISABLED'
                print '|    (ignoring this directory)\n|'
        if True == cont:
            continue

        try:
            path = os.path.join(current_module, MODULE_INFO_FILE)
            (module_name, info) = parse_xml_info(path)
            print '|    state:        ' + 'ENABLED'
            print '|    version:      ' + info['version'] + '\n|'
            module_info[module_name] = info
        except:
            print '|\n|    WARNING parsing of module info file',
            print '\'' + path + '\' failed!'
            print '|    ...ignoring this directory\n|'

    return (module_info)

# Checks the module_info data structure for missing dependencies and conflicts
# between modules. Returns a
def check_dependencies(module_info):

    for current_module in module_info.keys():
        # Check for dependencies
        for require in module_info[current_module]['requires']:
            if False == (require['name'] in module_info.keys()):
                print '|\n|    ERROR ' + current_module,
                print 'requires module ' + require['name']
                sys.exit('|    ...abort current run. Please check module configuration\n|')
            else:
                req_version = module_info[require['name']]['version']

                if require.has_key('minversion') and req_version < require['minversion']:
                    print '|\n|    ERROR ' + current_module + ' requires module',
                    print require['name'] + ' at least in version ' + require['minversion']
                    sys.exit('|    ...abort current run. Please check module configuration\n|')
                if require.has_key('maxversion') and req_version > require['maxversion']:
                    print '|\n|    ERROR ' + current_module + ' requires module',
                    print require['name'] + ' at most in version ' + require['maxversion']
                    sys.exit('|    ...abort current run. Please check module configuration\n|')

        # Check for conflicts
        for conflict in module_info[current_module]['conflicts']:
            if conflict['name'] in module_info.keys():
                con_version = module_info[conflict['name']]['version']

                if False == ((conflict.has_key('minversion') and
                              con_version < conflict['minversion']) or
                             (conflict.has_key('maxversion') and
                              con_version > conflict['maxversion'])):
                    print '|    ERROR ' + current_module + ' conflicts with module ' + conflict['name'] + ' (version ' + con_version + ')'
                    sys.exit('|    ...abort current run. Please check module configuration\n|')

# Creates a C header file with the given filename an the needed includes,
# the number of init functions per application and an array of function
# pointers for each application
def create_header_files(applications, module_info):

    if False == os.path.isdir(HEADER_FILE_DIR):
        os.mkdir(HEADER_FILE_DIR)

    for current_app in applications:

        hdr_file_path = os.path.join(HEADER_FILE_DIR,
                                     current_app + HEADER_FILE_SUFFIX)

        try:
            hdr_file = open(hdr_file_path, 'w')
            try:
                app_string = 'HIP_MODULES_' + current_app.upper() + '_MODULES_H'
                hdr_file.write('/* ' + WARNING_STRING + ' */\n')
                hdr_file.write('#ifndef ' + app_string + '\n')
                hdr_file.write('#define ' + app_string + '\n')

                info_string  = 'struct module_info ' + current_app
                info_string += '_modules[] = {'
                first_loop           = True
                num_spaces           = len(info_string)
                num_modules          = 0
                max_required_modules = 0

                for current_module in module_info:
                    if module_info[current_module]['application'].has_key(current_app):
                        app_info = module_info[current_module]['application'][current_app]
                        num_modules += 1
                        hdr_file.write('\n#include \"' + app_info['header_file'] + '\"')

                        num_required_modules = len(module_info[current_module]['requires'])
                        if num_required_modules > max_required_modules:
                            max_required_modules = num_required_modules
                        if first_loop != True:
                            info_string += ',\n'
                            for i in range(num_spaces):
                                info_string += ' '
                        info_string += '{"' + current_module + '", '
                        info_string += str(num_required_modules) + ', '

                        first_loop_1 = True
                        info_string += '{'
                        for required_module in module_info[current_module]['requires']:
                            if first_loop_1 != True:
                                info_string += ', '
                            info_string += '"' + required_module['name'] + '"'
                            first_loop_1 = False
                        info_string += '}'
                        info_string += ', &' + app_info['init_function'] + '}'
                        first_loop = False

                info_string += '};'

                info_struct  = '\n\n#define MAX_REQUIRED_MODULES '
                info_struct += str(max_required_modules)
                info_struct += '\n\nstruct module_info {\n'
                info_struct += '    const char *name;\n'
                info_struct += '    const int   num_required_moduels;\n'
                info_struct += '    const char *required_modules_hipd['
                info_struct += 'MAX_REQUIRED_MODULES];\n'
                info_struct += '    int       (*init_function)(void);\n'
                info_struct += '};\n\n'
                hdr_file.write(info_struct)
                hdr_file.write('/* Number of modules - determined during build process. */')
                hdr_file.write('\nconst int ' + current_app + '_num_modules')
                hdr_file.write(' = ' + str(num_modules) + ';\n\n')

                hdr_file.write(info_string)

                hdr_file.write('\n\n#endif /* ' + app_string + ' */\n')
                print '|    created file: ' + hdr_file_path
            finally:
                hdr_file.close()
        except IOError:
            sys.exit('Error on creating header files')

### Main program ###
def main():
    srcdir = None
    disabled_modules = None
    applications = set(['hipd'])

    try:
        opts, args = getopt.getopt(sys.argv[1:],
                                   "s:d:",
                                   ["srcdir=", "disabled_modules="])
    except getopt.GetoptError, err:
        print str(err)
        sys.exit(2)
    for o, a in opts:
        if o in ("-s", "--srcdir"):
            srcdir = a
        elif o in ("-d", "--disabled_modules"):
            disabled_modules = a
        else:
            assert False, "unhandled option"

    if disabled_modules:
        disabled_modules = disabled_modules.rsplit(',')

    (module_info) = read_module_info(os.path.join(srcdir, MODULES_DIR),
                                     disabled_modules)

    check_dependencies(module_info)

    create_header_files(applications, module_info)

if __name__ == "__main__":
    main()